Skip to content

Commit

Permalink
pythongh-92530: Fix an issue that occurred after interrupting threadi…
Browse files Browse the repository at this point in the history
…ng.Condition.notify (pythonGH-92534)

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 70af994)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
serhiy-storchaka authored and miss-islington committed May 16, 2022
1 parent 36d42e7 commit 22b41ab
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 deletions.
21 changes: 14 additions & 7 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,21 @@ def notify(self, n=1):
"""
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:
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:
all_waiters.remove(waiter)
waiters.remove(waiter)
except ValueError:
pass

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix an issue that occurred after interrupting
:func:`threading.Condition.notify`.

0 comments on commit 22b41ab

Please sign in to comment.