about summary refs log tree commit diff
path: root/src/libstd/sync
diff options
context:
space:
mode:
authorAshley Mannix <ashleymannix@live.com.au>2020-06-30 18:27:21 +1000
committerAshley Mannix <ashleymannix@live.com.au>2020-07-17 07:25:32 +1000
commitd1017940d77f35f841008c3e108e3da5e48a592f (patch)
tree73e377a65f41111d15d2355e490bd727d4be8649 /src/libstd/sync
parentd1263f5e66d31ad170c524a70aa5f21e08474326 (diff)
downloadrust-d1017940d77f35f841008c3e108e3da5e48a592f.tar.gz
rust-d1017940d77f35f841008c3e108e3da5e48a592f.zip
remove inlined lazy::Waiter in favor of sync::Once
Diffstat (limited to 'src/libstd/sync')
-rw-r--r--src/libstd/sync/once.rs18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 7dc822db3d0..1fce5dc0352 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -132,6 +132,7 @@ unsafe impl Send for Once {}
 #[derive(Debug)]
 pub struct OnceState {
     poisoned: bool,
+    set_state_on_drop_to: Cell<usize>,
 }
 
 /// Initialization value for static [`Once`] values.
@@ -321,7 +322,7 @@ impl Once {
         }
 
         let mut f = Some(f);
-        self.call_inner(true, &mut |p| f.take().unwrap()(&OnceState { poisoned: p }));
+        self.call_inner(true, &mut |p| f.take().unwrap()(p));
     }
 
     /// Returns `true` if some `call_once` call has completed
@@ -385,7 +386,7 @@ impl Once {
     // currently no way to take an `FnOnce` and call it via virtual dispatch
     // without some allocation overhead.
     #[cold]
-    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(bool)) {
+    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&OnceState)) {
         let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
         loop {
             match state_and_queue {
@@ -413,8 +414,9 @@ impl Once {
                     };
                     // Run the initialization function, letting it know if we're
                     // poisoned or not.
-                    init(state_and_queue == POISONED);
-                    waiter_queue.set_state_on_drop_to = COMPLETE;
+                    let init_state = OnceState { poisoned: state_and_queue == POISONED, set_state_on_drop_to: Cell::new(COMPLETE) };
+                    init(&init_state);
+                    waiter_queue.set_state_on_drop_to = init_state.set_state_on_drop_to.get();
                     break;
                 }
                 _ => {
@@ -554,6 +556,14 @@ impl OnceState {
     pub fn poisoned(&self) -> bool {
         self.poisoned
     }
+
+    /// Poison the associated [`Once`] without explicitly panicking.
+    ///
+    /// [`Once`]: struct.Once.html
+    // NOTE: This is currently only exposed for the `lazy` module
+    pub(crate) fn poison(&self) {
+        self.set_state_on_drop_to.set(POISONED);
+    }
 }
 
 #[cfg(all(test, not(target_os = "emscripten")))]