summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/lock_tests.py15
1 files changed, 15 insertions, 0 deletions
diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py
index 1a24bde..1cbcea2 100644
--- a/Lib/test/lock_tests.py
+++ b/Lib/test/lock_tests.py
@@ -418,6 +418,17 @@ class ConditionTests(BaseTestCase):
self.assertRaises(RuntimeError, cond.notify)
def _check_notify(self, cond):
+ # Note that this test is sensitive to timing. If the worker threads
+ # don't execute in a timely fashion, the main thread may think they
+ # are further along then they are. The main thread therefore issues
+ # _wait() statements to try to make sure that it doesn't race ahead
+ # of the workers.
+ # Secondly, this test assumes that condition variables are not subject
+ # to spurious wakeups. The absence of spurious wakeups is an implementation
+ # detail of Condition Cariables in current CPython, but in general, not
+ # a guaranteed property of condition variables as a programming
+ # construct. In particular, it is possible that this can no longer
+ # be conveniently guaranteed should their implementation ever change.
N = 5
results1 = []
results2 = []
@@ -445,6 +456,9 @@ class ConditionTests(BaseTestCase):
_wait()
self.assertEqual(results1, [(True, 1)] * 3)
self.assertEqual(results2, [])
+ # first wait, to ensure all workers settle into cond.wait() before
+ # we continue. See issue #8799
+ _wait()
# Notify 5 threads: they might be in their first or second wait
cond.acquire()
cond.notify(5)
@@ -455,6 +469,7 @@ class ConditionTests(BaseTestCase):
_wait()
self.assertEqual(results1, [(True, 1)] * 3 + [(True, 2)] * 2)
self.assertEqual(results2, [(True, 2)] * 3)
+ _wait() # make sure all workers settle into cond.wait()
# Notify all threads: they are all in their second wait
cond.acquire()
cond.notify_all()