diff options
| author | joboet <jonasboettiger@icloud.com> | 2024-07-12 13:17:43 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2024-07-31 17:44:10 +0200 |
| commit | 1d49aad8445881ac060cfae0e351207c05f82dfd (patch) | |
| tree | a9e70337c173b5423c56b599c19fc68fb8047cff /library/std/src/sys/sync | |
| parent | cf11f499b37e557e41f5eeac157c623d08e0068d (diff) | |
std: fix busy-waiting in `Once::wait_force`, add more tests
Diffstat (limited to 'library/std/src/sys/sync')
| -rw-r--r-- | library/std/src/sys/sync/once/queue.rs | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs index 7a020c94080..86f72c82008 100644 --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -153,7 +153,7 @@ impl Once { panic!("Once instance has previously been poisoned"); } _ => { - current = wait(&self.state_and_queue, current); + current = wait(&self.state_and_queue, current, !ignore_poisoning); } } } @@ -216,14 +216,18 @@ impl Once { // All other values must be RUNNING with possibly a // pointer to the waiter queue in the more significant bits. assert!(state == RUNNING); - current = wait(&self.state_and_queue, current); + current = wait(&self.state_and_queue, current, true); } } } } } -fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAndQueue { +fn wait( + state_and_queue: &AtomicPtr<()>, + mut current: StateAndQueue, + return_on_poisoned: bool, +) -> StateAndQueue { let node = &Waiter { thread: Cell::new(Some(thread::current())), signaled: AtomicBool::new(false), @@ -235,7 +239,7 @@ fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAnd let queue = to_queue(current); // If initialization has finished, return. - if matches!(state, POISONED | COMPLETE) { + if state == COMPLETE || (return_on_poisoned && state == POISONED) { return current; } |
