@@ -347,6 +347,17 @@ def test_unacquired_notify(self):
347347 self .assertRaises (RuntimeError , cond .notify )
348348
349349 def _check_notify (self , cond ):
350+ # Note that this test is sensitive to timing. If the worker threads
351+ # don't execute in a timely fashion, the main thread may think they
352+ # are further along then they are. The main thread therefore issues
353+ # _wait() statements to try to make sure that it doesn't race ahead
354+ # of the workers.
355+ # Secondly, this test assumes that condition variables are not subject
356+ # to spurious wakeups. The absence of spurious wakeups is an implementation
357+ # detail of Condition Cariables in current CPython, but in general, not
358+ # a guaranteed property of condition variables as a programming
359+ # construct. In particular, it is possible that this can no longer
360+ # be conveniently guaranteed should their implementation ever change.
350361 N = 5
351362 results1 = []
352363 results2 = []
@@ -374,6 +385,9 @@ def f():
374385 _wait ()
375386 self .assertEqual (results1 , [1 ] * 3 )
376387 self .assertEqual (results2 , [])
388+ # first wait, to ensure all workers settle into cond.wait() before
389+ # we continue. See issue #8799
390+ _wait ()
377391 # Notify 5 threads: they might be in their first or second wait
378392 cond .acquire ()
379393 cond .notify (5 )
@@ -384,6 +398,7 @@ def f():
384398 _wait ()
385399 self .assertEqual (results1 , [1 ] * 3 + [2 ] * 2 )
386400 self .assertEqual (results2 , [2 ] * 3 )
401+ _wait () # make sure all workers settle into cond.wait()
387402 # Notify all threads: they are all in their second wait
388403 cond .acquire ()
389404 cond .notify_all ()
0 commit comments