Issue #22185: Fix an occasional RuntimeError in threading.Condition.wait() caused by mutation of the waiters queue without holding the lock.

Patch by Doug Zongker.
This commit is contained in:
Antoine Pitrou 2014-08-29 23:27:33 +02:00
commit fa9211b11d
3 changed files with 11 additions and 5 deletions

View File

@ -290,6 +290,7 @@ class Condition:
waiter.acquire() waiter.acquire()
self._waiters.append(waiter) self._waiters.append(waiter)
saved_state = self._release_save() saved_state = self._release_save()
gotit = False
try: # restore state no matter what (e.g., KeyboardInterrupt) try: # restore state no matter what (e.g., KeyboardInterrupt)
if timeout is None: if timeout is None:
waiter.acquire() waiter.acquire()
@ -299,14 +300,14 @@ class Condition:
gotit = waiter.acquire(True, timeout) gotit = waiter.acquire(True, timeout)
else: else:
gotit = waiter.acquire(False) gotit = waiter.acquire(False)
return gotit
finally:
self._acquire_restore(saved_state)
if not gotit: if not gotit:
try: try:
self._waiters.remove(waiter) self._waiters.remove(waiter)
except ValueError: except ValueError:
pass pass
return gotit
finally:
self._acquire_restore(saved_state)
def wait_for(self, predicate, timeout=None): def wait_for(self, predicate, timeout=None):
"""Wait until a condition evaluates to True. """Wait until a condition evaluates to True.

View File

@ -1518,4 +1518,5 @@ Cheng Zhang
Kai Zhu Kai Zhu
Tarek Ziadé Tarek Ziadé
Gennadiy Zlobin Gennadiy Zlobin
Doug Zongker
Peter Åstrand Peter Åstrand

View File

@ -124,6 +124,10 @@ Core and Builtins
Library Library
------- -------
- Issue #22185: Fix an occasional RuntimeError in threading.Condition.wait()
caused by mutation of the waiters queue without holding the lock. Patch
by Doug Zongker.
- Issue #22287: On UNIX, _PyTime_gettimeofday() now uses - Issue #22287: On UNIX, _PyTime_gettimeofday() now uses
clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now
depends on the librt library on Solaris and on Linux (only with glibc older depends on the librt library on Solaris and on Linux (only with glibc older