Skip to content

Commit 25142d7

Browse files
committed
handle spurious returns of wait_timeout in test
1 parent 5413f7d commit 25142d7

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

library/std/tests/sync/condvar.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,31 @@ nonpoison_and_poison_unwrap_test!(
285285

286286
thread::scope(|s| {
287287
s.spawn(|| {
288+
// Sleep so that the other thread has a chance to encounter the
289+
// timeout.
288290
thread::sleep(Duration::from_secs(2));
289291
maybe_unwrap(sent.set(true));
290292
cond.notify_all();
291293
});
292294

293-
let guard = maybe_unwrap(sent.lock());
294-
// If there is internal overflow, this call will return almost
295-
// immediately, before the other thread has reached the `notify_all`
296-
let (guard, res) = maybe_unwrap(cond.wait_timeout(guard, Duration::from_secs(u64::MAX.div_ceil(1_000_000_000))));
297-
assert!(!res.timed_out());
298-
assert!(*guard);
295+
let mut guard = maybe_unwrap(sent.lock());
296+
// Loop until `sent` is set by the thread to guard against spurious
297+
// wakeups. If the `wait_timeout` happens just before the signal by
298+
// the other thread, such a spurious wakeup might prevent the
299+
// miscalculated timeout from occuring, but this is basically just
300+
// a smoke test anyway.
301+
loop {
302+
if *guard {
303+
break;
304+
}
305+
306+
// If there is internal overflow, this call will return almost
307+
// immediately, before the other thread has reached the `notify_all`,
308+
// and indicate a timeout.
309+
let (g, res) = maybe_unwrap(cond.wait_timeout(guard, Duration::from_secs(u64::MAX.div_ceil(1_000_000_000))));
310+
assert!(!res.timed_out());
311+
guard = g;
312+
}
299313
})
300314
}
301315
);

0 commit comments

Comments
 (0)