diff options
| author | bors <bors@rust-lang.org> | 2020-07-18 13:00:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-18 13:00:50 +0000 |
| commit | 7d31ffc1ac9e9ea356e896e63307168a64501b9d (patch) | |
| tree | aa1118412d2690e0e595788144b14970826c3d1f /src/libstd/sync | |
| parent | d3df8512d2c2afc6d2e7d8b5b951dd7f2ad77b02 (diff) | |
| parent | cae9c503b0d6de9702ca99bda95c081b1eb530f5 (diff) | |
Auto merge of #74468 - Manishearth:rollup-5nhvz80, r=Manishearth
Rollup of 11 pull requests Successful merges: - #72414 ( Add lazy initialization primitives to std) - #74069 (Compare tagged/niche-filling layout and pick the best one) - #74418 (ci: Set `shell: bash` as a default, remove duplicates) - #74441 (bootstrap.py: patch RPATH on NixOS to handle the new zlib dependency.) - #74444 (Add regression test for #69414) - #74448 (improper_ctypes_definitions: allow `Box`) - #74449 (Test codegen of compare_exchange operations) - #74450 (Fix `Safety` docs for `from_raw_parts_mut`) - #74453 (Use intra-doc links in `str` and `BTreeSet`) - #74457 (rustbuild: drop tool::should_install) - #74464 (Use pathdiff crate) Failed merges: r? @ghost
Diffstat (limited to 'src/libstd/sync')
| -rw-r--r-- | src/libstd/sync/once.rs | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 7dc822db3d0..64260990824 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,12 @@ 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 +559,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")))] |
