@@ -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 occurring, 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