summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-05-17 16:45:40 (GMT)
committerGitHub <noreply@github.com>2022-05-17 16:45:40 (GMT)
commit38d95b5500fa2d84d718c4190ba2f1b2f6806e6c (patch)
tree90ce41c1a673b68ee76fffd4d3ed4e601b95b817
parent76b81be41346774a2e12607aa4d55f34b170b8e9 (diff)
downloadcpython-38d95b5500fa2d84d718c4190ba2f1b2f6806e6c.zip
cpython-38d95b5500fa2d84d718c4190ba2f1b2f6806e6c.tar.gz
cpython-38d95b5500fa2d84d718c4190ba2f1b2f6806e6c.tar.bz2
[3.11] gh-92530: Fix an issue that occurred after interrupting threading.Condition.notify (GH-92534) (GH-92829)
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 70af994fee7c0850ae859727d9468a5f29375a38) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Automerge-Triggered-By: GH:serhiy-storchaka
-rw-r--r--Lib/threading.py21
-rw-r--r--Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst2
2 files changed, 16 insertions, 7 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index 642f93e..8e7cdf6 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
diff --git a/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst b/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst
new file mode 100644
index 0000000..8bb8ca0
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst
@@ -0,0 +1,2 @@
+Fix an issue that occurred after interrupting
+:func:`threading.Condition.notify`.