summaryrefslogtreecommitdiffstats
path: root/vendor/once_cell
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/once_cell')
-rw-r--r--vendor/once_cell/.cargo-checksum.json2
-rw-r--r--vendor/once_cell/CHANGELOG.md6
-rw-r--r--vendor/once_cell/Cargo.lock3
-rw-r--r--vendor/once_cell/Cargo.toml21
-rw-r--r--vendor/once_cell/src/imp_cs.rs78
-rw-r--r--vendor/once_cell/src/imp_pl.rs14
-rw-r--r--vendor/once_cell/src/imp_std.rs16
-rw-r--r--vendor/once_cell/src/lib.rs52
-rw-r--r--vendor/once_cell/src/race.rs5
-rw-r--r--vendor/once_cell/tests/it.rs45
10 files changed, 181 insertions, 61 deletions
diff --git a/vendor/once_cell/.cargo-checksum.json b/vendor/once_cell/.cargo-checksum.json
index 6f8adad72..8fb4b41d7 100644
--- a/vendor/once_cell/.cargo-checksum.json
+++ b/vendor/once_cell/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"f6198c1a83a8245a7b2ab062a316f3f97dfba190ac1d6bb47949e9c0cf4dac80","Cargo.lock":"e69c2663fe7efb3a4e463af446fa1367bd8e008100500137052ef15b84b02ebc","Cargo.toml":"d08e0411e5eda265a3359939f1fb646dff29ca38896222ffe0900b0af8e3ae70","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_pl.rs":"1959494004fb0ee7443e97c4abd8be69d7173fe2b66f8fff0bca7b5c8e512525","src/imp_std.rs":"33be3a0df87e092abd68280dc72d50534d273d17eb86940e7ba2b8a45da78a70","src/lib.rs":"88d2f7a63bd63f630733c86ea035b53e53f2f8d3c44f1025bc9bbe5ceaa7375f","src/race.rs":"5a19afca4b5510d09ca7317b96f5642725c58b0969b2bdeb7275ed674d061e5d","tests/it.rs":"4448a74a9898babfb943bae42ebfe3b07ec2b002ea39712127159955015d33b4"},"package":"e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"f624f016b8fa7e0f3aa46665f9fa7eb9ab46a02743fa14b29b3dad5bb9c57a9e","Cargo.lock":"f21b2f56fe0bd4911048ebeddc572a6ab6be3248a8de5f24f606bc4b96047455","Cargo.toml":"90819aab2f2f2696d640edcd5806293788279adf6b2f22edb04b25b37be82eb4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_cs.rs":"888fc76a1f4e55b1ece3ef748b0aa6a47be2d8d928c10f89ae6b4f12330c0e55","src/imp_pl.rs":"cd69042890c25fd3db97a4762abea4b814c961eadaf5d6ed7c7db17a6abd4c5b","src/imp_std.rs":"f13a5bfe08ac02eb0d5a0271cb5be9e8c534a81cddc3253aaca28b69bded8e65","src/lib.rs":"b1f8113fc779d6ea398ddb736fe5b3e3c4a63f23404569e4a08a5003bdd3774f","src/race.rs":"bb89ba6fe9420b8d3a173c1a484dde1b6a65289c5d72eb57cd3b0cca3ac23c04","tests/it.rs":"41f50496463a0036c45ed138f158d221d379e50a91ca452ba8ffe8caa7a59e3a"},"package":"86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"} \ No newline at end of file
diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md
index 005ce6951..5cf6ea6b7 100644
--- a/vendor/once_cell/CHANGELOG.md
+++ b/vendor/once_cell/CHANGELOG.md
@@ -4,6 +4,12 @@
-
+## 1.16.0
+
+- Add `no_std` implementation based on `critical-section`,
+ [#195](https://github.com/matklad/once_cell/pull/195).
+- Deprecate `atomic-polyfill` feature (use the new `critical-section` instead)
+
## 1.15.0
- Increase minimal supported Rust version to 1.56.0.
diff --git a/vendor/once_cell/Cargo.lock b/vendor/once_cell/Cargo.lock
index 83f83681a..b72bbabf5 100644
--- a/vendor/once_cell/Cargo.lock
+++ b/vendor/once_cell/Cargo.lock
@@ -74,9 +74,10 @@ checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
[[package]]
name = "once_cell"
-version = "1.15.0"
+version = "1.16.0"
dependencies = [
"atomic-polyfill",
+ "critical-section",
"crossbeam-utils",
"lazy_static",
"parking_lot_core",
diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml
index bde77ee9d..6587f4e52 100644
--- a/vendor/once_cell/Cargo.toml
+++ b/vendor/once_cell/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.56"
name = "once_cell"
-version = "1.15.0"
+version = "1.16.0"
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
exclude = [
"*.png",
@@ -34,7 +34,6 @@ categories = [
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/matklad/once_cell"
-resolver = "2"
[package.metadata.docs.rs]
all-features = true
@@ -67,15 +66,26 @@ required-features = ["std"]
name = "test_synchronization"
required-features = ["std"]
-[dependencies.atomic-polyfill]
+[dependencies.atomic_polyfill]
version = "1"
optional = true
+package = "atomic-polyfill"
+
+[dependencies.critical_section]
+version = "1"
+optional = true
+package = "critical-section"
[dependencies.parking_lot_core]
version = "0.9.3"
optional = true
default_features = false
+[dev-dependencies.critical_section]
+version = "1.1.1"
+features = ["std"]
+package = "critical-section"
+
[dev-dependencies.crossbeam-utils]
version = "0.8.7"
@@ -87,6 +97,11 @@ version = "1.2.0"
[features]
alloc = ["race"]
+atomic-polyfill = ["critical-section"]
+critical-section = [
+ "critical_section",
+ "atomic_polyfill",
+]
default = ["std"]
parking_lot = ["parking_lot_core"]
race = []
diff --git a/vendor/once_cell/src/imp_cs.rs b/vendor/once_cell/src/imp_cs.rs
new file mode 100644
index 000000000..668f18ec6
--- /dev/null
+++ b/vendor/once_cell/src/imp_cs.rs
@@ -0,0 +1,78 @@
+use core::panic::{RefUnwindSafe, UnwindSafe};
+
+use atomic_polyfill::{AtomicBool, Ordering};
+use critical_section::{CriticalSection, Mutex};
+
+use crate::unsync;
+
+pub(crate) struct OnceCell<T> {
+ initialized: AtomicBool,
+ // Use `unsync::OnceCell` internally since `Mutex` does not provide
+ // interior mutability and to be able to re-use `get_or_try_init`.
+ value: Mutex<unsync::OnceCell<T>>,
+}
+
+// Why do we need `T: Send`?
+// Thread A creates a `OnceCell` and shares it with
+// scoped thread B, which fills the cell, which is
+// then destroyed by A. That is, destructor observes
+// a sent value.
+unsafe impl<T: Sync + Send> Sync for OnceCell<T> {}
+unsafe impl<T: Send> Send for OnceCell<T> {}
+
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
+impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
+
+impl<T> OnceCell<T> {
+ pub(crate) const fn new() -> OnceCell<T> {
+ OnceCell { initialized: AtomicBool::new(false), value: Mutex::new(unsync::OnceCell::new()) }
+ }
+
+ pub(crate) const fn with_value(value: T) -> OnceCell<T> {
+ OnceCell {
+ initialized: AtomicBool::new(true),
+ value: Mutex::new(unsync::OnceCell::with_value(value)),
+ }
+ }
+
+ #[inline]
+ pub(crate) fn is_initialized(&self) -> bool {
+ self.initialized.load(Ordering::Acquire)
+ }
+
+ #[cold]
+ pub(crate) fn initialize<F, E>(&self, f: F) -> Result<(), E>
+ where
+ F: FnOnce() -> Result<T, E>,
+ {
+ critical_section::with(|cs| {
+ let cell = self.value.borrow(cs);
+ cell.get_or_try_init(f).map(|_| {
+ self.initialized.store(true, Ordering::Release);
+ })
+ })
+ }
+
+ /// Get the reference to the underlying value, without checking if the cell
+ /// is initialized.
+ ///
+ /// # Safety
+ ///
+ /// Caller must ensure that the cell is in initialized state, and that
+ /// the contents are acquired by (synchronized to) this thread.
+ pub(crate) unsafe fn get_unchecked(&self) -> &T {
+ debug_assert!(self.is_initialized());
+ // SAFETY: The caller ensures that the value is initialized and access synchronized.
+ crate::unwrap_unchecked(self.value.borrow(CriticalSection::new()).get())
+ }
+
+ #[inline]
+ pub(crate) fn get_mut(&mut self) -> Option<&mut T> {
+ self.value.get_mut().get_mut()
+ }
+
+ #[inline]
+ pub(crate) fn into_inner(self) -> Option<T> {
+ self.value.into_inner().into_inner()
+ }
+}
diff --git a/vendor/once_cell/src/imp_pl.rs b/vendor/once_cell/src/imp_pl.rs
index d80ca5e06..84d859386 100644
--- a/vendor/once_cell/src/imp_pl.rs
+++ b/vendor/once_cell/src/imp_pl.rs
@@ -1,6 +1,5 @@
use std::{
cell::UnsafeCell,
- hint,
panic::{RefUnwindSafe, UnwindSafe},
sync::atomic::{AtomicU8, Ordering},
};
@@ -59,7 +58,7 @@ impl<T> OnceCell<T> {
// but that is more complicated
// - finally, if it returns Ok, we store the value and store the flag with
// `Release`, which synchronizes with `Acquire`s.
- let f = unsafe { crate::take_unchecked(&mut f) };
+ let f = unsafe { crate::unwrap_unchecked(f.take()) };
match f() {
Ok(value) => unsafe {
// Safe b/c we have a unique access and no panic may happen
@@ -101,15 +100,8 @@ impl<T> OnceCell<T> {
/// the contents are acquired by (synchronized to) this thread.
pub(crate) unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
- let slot: &Option<T> = &*self.value.get();
- match slot {
- Some(value) => value,
- // This unsafe does improve performance, see `examples/bench`.
- None => {
- debug_assert!(false);
- hint::unreachable_unchecked()
- }
- }
+ let slot = &*self.value.get();
+ crate::unwrap_unchecked(slot.as_ref())
}
/// Gets the mutable reference to the underlying value.
diff --git a/vendor/once_cell/src/imp_std.rs b/vendor/once_cell/src/imp_std.rs
index 4d5b5fd32..5761f0184 100644
--- a/vendor/once_cell/src/imp_std.rs
+++ b/vendor/once_cell/src/imp_std.rs
@@ -5,15 +5,12 @@
use std::{
cell::{Cell, UnsafeCell},
- hint::unreachable_unchecked,
marker::PhantomData,
panic::{RefUnwindSafe, UnwindSafe},
sync::atomic::{AtomicBool, AtomicPtr, Ordering},
thread::{self, Thread},
};
-use crate::take_unchecked;
-
#[derive(Debug)]
pub(crate) struct OnceCell<T> {
// This `queue` field is the core of the implementation. It encodes two
@@ -81,7 +78,7 @@ impl<T> OnceCell<T> {
initialize_or_wait(
&self.queue,
Some(&mut || {
- let f = unsafe { take_unchecked(&mut f) };
+ let f = unsafe { crate::unwrap_unchecked(f.take()) };
match f() {
Ok(value) => {
unsafe { *slot = Some(value) };
@@ -111,15 +108,8 @@ impl<T> OnceCell<T> {
/// the contents are acquired by (synchronized to) this thread.
pub(crate) unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
- let slot: &Option<T> = &*self.value.get();
- match slot {
- Some(value) => value,
- // This unsafe does improve performance, see `examples/bench`.
- None => {
- debug_assert!(false);
- unreachable_unchecked()
- }
- }
+ let slot = &*self.value.get();
+ crate::unwrap_unchecked(slot.as_ref())
}
/// Gets the mutable reference to the underlying value.
diff --git a/vendor/once_cell/src/lib.rs b/vendor/once_cell/src/lib.rs
index 6de1e3eeb..41313f736 100644
--- a/vendor/once_cell/src/lib.rs
+++ b/vendor/once_cell/src/lib.rs
@@ -269,7 +269,7 @@
//!
//! This crate's minimum supported `rustc` version is `1.56.0`.
//!
-//! If only the `std` feature is enabled, MSRV will be updated conservatively.
+//! If only the `std` feature is enabled, MSRV will be updated conservatively, supporting at least latest 8 versions of the compiler.
//! When using other features, like `parking_lot`, MSRV might be updated more frequently, up to the latest stable.
//! In both cases, increasing MSRV is *not* considered a semver-breaking change.
//!
@@ -332,13 +332,15 @@
#[cfg(feature = "alloc")]
extern crate alloc;
-#[cfg(feature = "std")]
-#[cfg(feature = "parking_lot")]
+#[cfg(all(feature = "critical-section", not(feature = "std")))]
+#[path = "imp_cs.rs"]
+mod imp;
+
+#[cfg(all(feature = "std", feature = "parking_lot"))]
#[path = "imp_pl.rs"]
mod imp;
-#[cfg(feature = "std")]
-#[cfg(not(feature = "parking_lot"))]
+#[cfg(all(feature = "std", not(feature = "parking_lot")))]
#[path = "imp_std.rs"]
mod imp;
@@ -346,11 +348,13 @@ mod imp;
pub mod unsync {
use core::{
cell::{Cell, UnsafeCell},
- fmt, hint, mem,
+ fmt, mem,
ops::{Deref, DerefMut},
panic::{RefUnwindSafe, UnwindSafe},
};
+ use super::unwrap_unchecked;
+
/// A cell which can be written to only once. It is not thread safe.
///
/// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
@@ -442,6 +446,7 @@ pub mod unsync {
/// Gets a reference to the underlying value.
///
/// Returns `None` if the cell is empty.
+ #[inline]
pub fn get(&self) -> Option<&T> {
// Safe due to `inner`'s invariant
unsafe { &*self.inner.get() }.as_ref()
@@ -463,6 +468,7 @@ pub mod unsync {
/// *cell.get_mut().unwrap() = 93;
/// assert_eq!(cell.get(), Some(&93));
/// ```
+ #[inline]
pub fn get_mut(&mut self) -> Option<&mut T> {
// Safe because we have unique access
unsafe { &mut *self.inner.get() }.as_mut()
@@ -510,16 +516,14 @@ pub mod unsync {
if let Some(old) = self.get() {
return Err((old, value));
}
+
let slot = unsafe { &mut *self.inner.get() };
// This is the only place where we set the slot, no races
// due to reentrancy/concurrency are possible, and we've
// checked that slot is currently `None`, so this write
// maintains the `inner`'s invariant.
*slot = Some(value);
- Ok(match &*slot {
- Some(value) => value,
- None => unsafe { hint::unreachable_unchecked() },
- })
+ Ok(unsafe { unwrap_unchecked(slot.as_ref()) })
}
/// Gets the contents of the cell, initializing it with `f`
@@ -592,7 +596,7 @@ pub mod unsync {
// `assert`, while keeping `set/get` would be sound, but it seems
// better to panic, rather than to silently use an old value.
assert!(self.set(val).is_ok(), "reentrant init");
- Ok(self.get().unwrap())
+ Ok(unsafe { unwrap_unchecked(self.get()) })
}
/// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
@@ -814,16 +818,16 @@ pub mod unsync {
}
/// Thread-safe, blocking version of `OnceCell`.
-#[cfg(feature = "std")]
+#[cfg(any(feature = "std", feature = "critical-section"))]
pub mod sync {
- use std::{
+ use core::{
cell::Cell,
fmt, mem,
ops::{Deref, DerefMut},
panic::RefUnwindSafe,
};
- use crate::{imp::OnceCell as Imp, take_unchecked};
+ use super::{imp::OnceCell as Imp, unwrap_unchecked};
/// A thread-safe cell which can be written to only once.
///
@@ -942,8 +946,9 @@ pub mod sync {
/// // Will return 92, but might block until the other thread does `.set`.
/// let value: &u32 = cell.wait();
/// assert_eq!(*value, 92);
- /// t.join().unwrap();;
+ /// t.join().unwrap();
/// ```
+ #[cfg(feature = "std")]
pub fn wait(&self) -> &T {
if !self.0.is_initialized() {
self.0.wait()
@@ -969,6 +974,7 @@ pub mod sync {
/// cell.set(92).unwrap();
/// cell = OnceCell::new();
/// ```
+ #[inline]
pub fn get_mut(&mut self) -> Option<&mut T> {
self.0.get_mut()
}
@@ -980,6 +986,7 @@ pub mod sync {
///
/// Caller must ensure that the cell is in initialized state, and that
/// the contents are acquired by (synchronized to) this thread.
+ #[inline]
pub unsafe fn get_unchecked(&self) -> &T {
self.0.get_unchecked()
}
@@ -1031,7 +1038,7 @@ pub mod sync {
/// ```
pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
let mut value = Some(value);
- let res = self.get_or_init(|| unsafe { take_unchecked(&mut value) });
+ let res = self.get_or_init(|| unsafe { unwrap_unchecked(value.take()) });
match value {
None => Ok(res),
Some(value) => Err((res, value)),
@@ -1109,6 +1116,7 @@ pub mod sync {
if let Some(value) = self.get() {
return Ok(value);
}
+
self.0.initialize(f)?;
// Safe b/c value is initialized.
@@ -1164,6 +1172,7 @@ pub mod sync {
/// cell.set("hello".to_string()).unwrap();
/// assert_eq!(cell.into_inner(), Some("hello".to_string()));
/// ```
+ #[inline]
pub fn into_inner(self) -> Option<T> {
self.0.into_inner()
}
@@ -1356,13 +1365,14 @@ pub mod sync {
#[cfg(feature = "race")]
pub mod race;
-#[cfg(feature = "std")]
-unsafe fn take_unchecked<T>(val: &mut Option<T>) -> T {
- match val.take() {
- Some(it) => it,
+// Remove once MSRV is at least 1.58.
+#[inline]
+unsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
+ match val {
+ Some(value) => value,
None => {
debug_assert!(false);
- std::hint::unreachable_unchecked()
+ core::hint::unreachable_unchecked()
}
}
}
diff --git a/vendor/once_cell/src/race.rs b/vendor/once_cell/src/race.rs
index e83e0b921..fd255c4c7 100644
--- a/vendor/once_cell/src/race.rs
+++ b/vendor/once_cell/src/race.rs
@@ -19,9 +19,9 @@
//! `Acquire` and `Release` have very little performance overhead on most
//! architectures versus `Relaxed`.
-#[cfg(feature = "atomic-polyfill")]
+#[cfg(feature = "critical-section")]
use atomic_polyfill as atomic;
-#[cfg(not(feature = "atomic-polyfill"))]
+#[cfg(not(feature = "critical-section"))]
use core::sync::atomic;
use atomic::{AtomicUsize, Ordering};
@@ -165,6 +165,7 @@ impl OnceBool {
fn from_usize(value: NonZeroUsize) -> bool {
value.get() == 1
}
+
#[inline]
fn to_usize(value: bool) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(if value { 1 } else { 2 }) }
diff --git a/vendor/once_cell/tests/it.rs b/vendor/once_cell/tests/it.rs
index 410b93b64..d18f0a165 100644
--- a/vendor/once_cell/tests/it.rs
+++ b/vendor/once_cell/tests/it.rs
@@ -249,10 +249,16 @@ mod unsync {
}
}
-#[cfg(feature = "std")]
+#[cfg(any(feature = "std", feature = "critical-section"))]
mod sync {
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+ #[cfg(feature = "std")]
+ use std::sync::Barrier;
+
+ #[cfg(not(feature = "std"))]
+ use core::cell::Cell;
+
use crossbeam_utils::thread::scope;
use once_cell::sync::{Lazy, OnceCell};
@@ -354,6 +360,7 @@ mod sync {
assert_eq!(cell.get(), Some(&"hello".to_string()));
}
+ #[cfg(feature = "std")]
#[test]
fn wait() {
let cell: OnceCell<String> = OnceCell::new();
@@ -365,9 +372,9 @@ mod sync {
.unwrap();
}
+ #[cfg(feature = "std")]
#[test]
fn get_or_init_stress() {
- use std::sync::Barrier;
let n_threads = if cfg!(miri) { 30 } else { 1_000 };
let n_cells = if cfg!(miri) { 30 } else { 1_000 };
let cells: Vec<_> = std::iter::repeat_with(|| (Barrier::new(n_threads), OnceCell::new()))
@@ -430,6 +437,7 @@ mod sync {
#[test]
#[cfg_attr(miri, ignore)] // miri doesn't support processes
+ #[cfg(feature = "std")]
fn reentrant_init() {
let examples_dir = {
let mut exe = std::env::current_exe().unwrap();
@@ -457,6 +465,20 @@ mod sync {
}
}
+ #[cfg(not(feature = "std"))]
+ #[test]
+ #[should_panic(expected = "reentrant init")]
+ fn reentrant_init() {
+ let x: OnceCell<Box<i32>> = OnceCell::new();
+ let dangling_ref: Cell<Option<&i32>> = Cell::new(None);
+ x.get_or_init(|| {
+ let r = x.get_or_init(|| Box::new(92));
+ dangling_ref.set(Some(r));
+ Box::new(62)
+ });
+ eprintln!("use after free: {:?}", dangling_ref.get().unwrap());
+ }
+
#[test]
fn lazy_new() {
let called = AtomicUsize::new(0);
@@ -636,10 +658,9 @@ mod sync {
}
}
+ #[cfg(feature = "std")]
#[test]
fn get_does_not_block() {
- use std::sync::Barrier;
-
let cell = OnceCell::new();
let barrier = Barrier::new(2);
scope(|scope| {
@@ -671,12 +692,11 @@ mod sync {
#[cfg(feature = "race")]
mod race {
+ #[cfg(feature = "std")]
+ use std::sync::Barrier;
use std::{
num::NonZeroUsize,
- sync::{
- atomic::{AtomicUsize, Ordering::SeqCst},
- Barrier,
- },
+ sync::atomic::{AtomicUsize, Ordering::SeqCst},
};
use crossbeam_utils::thread::scope;
@@ -728,6 +748,7 @@ mod race {
assert_eq!(cell.get(), Some(val1));
}
+ #[cfg(feature = "std")]
#[test]
fn once_non_zero_usize_first_wins() {
let val1 = NonZeroUsize::new(92).unwrap();
@@ -807,12 +828,16 @@ mod race {
#[cfg(all(feature = "race", feature = "alloc"))]
mod race_once_box {
+ #[cfg(feature = "std")]
+ use std::sync::Barrier;
use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
- Arc, Barrier,
+ Arc,
};
+ #[cfg(feature = "std")]
use crossbeam_utils::thread::scope;
+
use once_cell::race::OnceBox;
#[derive(Default)]
@@ -842,6 +867,7 @@ mod race_once_box {
}
}
+ #[cfg(feature = "std")]
#[test]
fn once_box_smoke_test() {
let heap = Heap::default();
@@ -896,6 +922,7 @@ mod race_once_box {
assert_eq!(heap.total(), 0);
}
+ #[cfg(feature = "std")]
#[test]
fn once_box_first_wins() {
let cell = OnceBox::new();