std: fix busy-waiting in Once::wait_force
, add more tests · patricklam/verify-rust-std@cc6f37f (original) (raw)
`@@ -153,7 +153,7 @@ impl Once {
`
153
153
`panic!("Once instance has previously been poisoned");
`
154
154
`}
`
155
155
` _ => {
`
156
``
`-
current = wait(&self.state_and_queue, current);
`
``
156
`+
current = wait(&self.state_and_queue, current, !ignore_poisoning);
`
157
157
`}
`
158
158
`}
`
159
159
`}
`
`@@ -216,14 +216,18 @@ impl Once {
`
216
216
`// All other values must be RUNNING with possibly a
`
217
217
`// pointer to the waiter queue in the more significant bits.
`
218
218
`assert!(state == RUNNING);
`
219
``
`-
current = wait(&self.state_and_queue, current);
`
``
219
`+
current = wait(&self.state_and_queue, current, true);
`
220
220
`}
`
221
221
`}
`
222
222
`}
`
223
223
`}
`
224
224
`}
`
225
225
``
226
``
`-
fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAndQueue {
`
``
226
`+
fn wait(
`
``
227
`+
state_and_queue: &AtomicPtr<()>,
`
``
228
`+
mut current: StateAndQueue,
`
``
229
`+
return_on_poisoned: bool,
`
``
230
`+
) -> StateAndQueue {
`
227
231
`let node = &Waiter {
`
228
232
`thread: Cell::new(Some(thread::current())),
`
229
233
`signaled: AtomicBool::new(false),
`
`@@ -235,7 +239,7 @@ fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAnd
`
235
239
`let queue = to_queue(current);
`
236
240
``
237
241
`// If initialization has finished, return.
`
238
``
`-
if matches!(state, POISONED | COMPLETE) {
`
``
242
`+
if state == COMPLETE || (return_on_poisoned && state == POISONED) {
`
239
243
`return current;
`
240
244
`}
`
241
245
``