mirror of
https://github.com/python/cpython.git
synced 2025-07-29 14:15:07 +00:00
gh-92530: Fix an issue that occurred after interrupting threading.Condition.notify (GH-92534) (GH-92830)
If Condition.notify() was interrupted just after it released the waiter lock,
but before removing it from the queue, the following calls of notify() failed
with RuntimeError: cannot release un-acquired lock.
(cherry picked from commit 70af994fee
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
cfb9248cd4
commit
e29ce9a5f1
2 changed files with 16 additions and 7 deletions
|
@ -368,14 +368,21 @@ class Condition:
|
|||
"""
|
||||
if not self._is_owned():
|
||||
raise RuntimeError("cannot notify on un-acquired lock")
|
||||
all_waiters = self._waiters
|
||||
waiters_to_notify = _deque(_islice(all_waiters, n))
|
||||
if not waiters_to_notify:
|
||||
return
|
||||
for waiter in waiters_to_notify:
|
||||
waiter.release()
|
||||
waiters = self._waiters
|
||||
while waiters and n > 0:
|
||||
waiter = waiters[0]
|
||||
try:
|
||||
all_waiters.remove(waiter)
|
||||
waiter.release()
|
||||
except RuntimeError:
|
||||
# gh-92530: The previous call of notify() released the lock,
|
||||
# but was interrupted before removing it from the queue.
|
||||
# It can happen if a signal handler raises an exception,
|
||||
# like CTRL+C which raises KeyboardInterrupt.
|
||||
pass
|
||||
else:
|
||||
n -= 1
|
||||
try:
|
||||
waiters.remove(waiter)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue