aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/threading.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py21
1 files changed, 14 insertions, 7 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index 40edcde1153..a3df587f106 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -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:
+ 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