Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ded0348

Browse files
author
Charles-François Natali
committed
Issue #13502: threading: Fix a race condition in Event.wait() that made it
return False when the event was set and cleared right after.
1 parent b52e7a9 commit ded0348

4 files changed

Lines changed: 27 additions & 5 deletions

File tree

Doc/library/threading.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,10 @@ An event object manages an internal flag that can be set to true with the
782782
floating point number specifying a timeout for the operation in seconds
783783
(or fractions thereof).
784784

785-
This method returns the internal flag on exit, so it will always return
786-
``True`` except if a timeout is given and the operation times out.
785+
This method returns true if and only if the internal flag has been set to
786+
true, either before the wait call or after the wait starts, so it will
787+
always return ``True`` except if a timeout is given and the operation
788+
times out.
787789

788790
.. versionchanged:: 3.1
789791
Previously, the method always returned ``None``.

Lib/test/lock_tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,22 @@ def f():
351351
for r, dt in results2:
352352
self.assertTrue(r)
353353

354+
def test_set_and_clear(self):
355+
# Issue #13502: check that wait() returns true even when the event is
356+
# cleared before the waiting thread is woken up.
357+
evt = self.eventtype()
358+
results = []
359+
N = 5
360+
def f():
361+
results.append(evt.wait(1))
362+
b = Bunch(f, N)
363+
b.wait_for_started()
364+
time.sleep(0.5)
365+
evt.set()
366+
evt.clear()
367+
b.wait_for_finished()
368+
self.assertEqual(results, [True] * N)
369+
354370

355371
class ConditionTests(BaseTestCase):
356372
"""

Lib/threading.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,10 @@ def clear(self):
418418
def wait(self, timeout=None):
419419
self._cond.acquire()
420420
try:
421-
if not self._flag:
422-
self._cond.wait(timeout)
423-
return self._flag
421+
signaled = self._flag
422+
if not signaled:
423+
signaled = self._cond.wait(timeout)
424+
return signaled
424425
finally:
425426
self._cond.release()
426427

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ Core and Builtins
9797
Library
9898
-------
9999

100+
- Issue #13502: threading: Fix a race condition in Event.wait() that made it
101+
return False when the event was set and cleared right after.
102+
100103
- Issue #12926: Fix a bug in tarfile's link extraction.
101104

102105
- Issue #13696: Fix the 302 Relative URL Redirection problem.

0 commit comments

Comments
 (0)