@@ -418,6 +418,17 @@ def test_unacquired_notify(self):
418
418
self .assertRaises (RuntimeError , cond .notify )
419
419
420
420
def _check_notify (self , cond ):
421
+ # Note that this test is sensitive to timing. If the worker threads
422
+ # don't execute in a timely fashion, the main thread may think they
423
+ # are further along then they are. The main thread therefore issues
424
+ # _wait() statements to try to make sure that it doesn't race ahead
425
+ # of the workers.
426
+ # Secondly, this test assumes that condition variables are not subject
427
+ # to spurious wakeups. The absence of spurious wakeups is an implementation
428
+ # detail of Condition Cariables in current CPython, but in general, not
429
+ # a guaranteed property of condition variables as a programming
430
+ # construct. In particular, it is possible that this can no longer
431
+ # be conveniently guaranteed should their implementation ever change.
421
432
N = 5
422
433
results1 = []
423
434
results2 = []
@@ -445,6 +456,9 @@ def f():
445
456
_wait ()
446
457
self .assertEqual (results1 , [(True , 1 )] * 3 )
447
458
self .assertEqual (results2 , [])
459
+ # first wait, to ensure all workers settle into cond.wait() before
460
+ # we continue. See issue #8799
461
+ _wait ()
448
462
# Notify 5 threads: they might be in their first or second wait
449
463
cond .acquire ()
450
464
cond .notify (5 )
@@ -455,6 +469,7 @@ def f():
455
469
_wait ()
456
470
self .assertEqual (results1 , [(True , 1 )] * 3 + [(True , 2 )] * 2 )
457
471
self .assertEqual (results2 , [(True , 2 )] * 3 )
472
+ _wait () # make sure all workers settle into cond.wait()
458
473
# Notify all threads: they are all in their second wait
459
474
cond .acquire ()
460
475
cond .notify_all ()
0 commit comments