]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #13502: threading: Fix a race condition in Event.wait() that made it
authorCharles-François Natali <neologix@free.fr>
Sat, 7 Jan 2012 17:24:56 +0000 (18:24 +0100)
committerCharles-François Natali <neologix@free.fr>
Sat, 7 Jan 2012 17:24:56 +0000 (18:24 +0100)
return False when the event was set and cleared right after.

Doc/library/threading.rst
Lib/test/lock_tests.py
Lib/threading.py
Misc/NEWS

index c226dd46c8616374a044072c060aea60d9776836..9b3affd979bd02552f5a4942ff154c1d2cc7f357 100644 (file)
@@ -782,8 +782,10 @@ An event object manages an internal flag that can be set to true with the
       floating point number specifying a timeout for the operation in seconds
       (or fractions thereof).
 
-      This method returns the internal flag on exit, so it will always return
-      ``True`` except if a timeout is given and the operation times out.
+      This method returns true if and only if the internal flag has been set to
+      true, either before the wait call or after the wait starts, so it will
+      always return ``True`` except if a timeout is given and the operation
+      times out.
 
       .. versionchanged:: 3.1
          Previously, the method always returned ``None``.
index 30148e638a687ff2f219b084fe11cac87879adf1..094cc7a4597f9fe883c90549e83276cbb11ed778 100644 (file)
@@ -351,6 +351,22 @@ class EventTests(BaseTestCase):
         for r, dt in results2:
             self.assertTrue(r)
 
+    def test_set_and_clear(self):
+        # Issue #13502: check that wait() returns true even when the event is
+        # cleared before the waiting thread is woken up.
+        evt = self.eventtype()
+        results = []
+        N = 5
+        def f():
+            results.append(evt.wait(1))
+        b = Bunch(f, N)
+        b.wait_for_started()
+        time.sleep(0.5)
+        evt.set()
+        evt.clear()
+        b.wait_for_finished()
+        self.assertEqual(results, [True] * N)
+
 
 class ConditionTests(BaseTestCase):
     """
index 043e6c82afbac0d63db75f4362bd48dde6b0cc9f..fe92f106365f5e8f4253f1b51112de1f8429af3f 100644 (file)
@@ -418,9 +418,10 @@ class _Event(_Verbose):
     def wait(self, timeout=None):
         self._cond.acquire()
         try:
-            if not self._flag:
-                self._cond.wait(timeout)
-            return self._flag
+            signaled = self._flag
+            if not signaled:
+                signaled = self._cond.wait(timeout)
+            return signaled
         finally:
             self._cond.release()
 
index 7adf4f79773b7f29a90b25e0606c86a71dc24ab4..9212f9e622932792abe2324914ab4bb0a16deacd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -97,6 +97,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #13502: threading: Fix a race condition in Event.wait() that made it
+  return False when the event was set and cleared right after.
+
 - Issue #12926: Fix a bug in tarfile's link extraction.
 
 - Issue #13696: Fix the 302 Relative URL Redirection problem.