diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-05-17 16:45:40 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-17 16:45:40 (GMT) |
commit | 38d95b5500fa2d84d718c4190ba2f1b2f6806e6c (patch) | |
tree | 90ce41c1a673b68ee76fffd4d3ed4e601b95b817 | |
parent | 76b81be41346774a2e12607aa4d55f34b170b8e9 (diff) | |
download | cpython-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.py | 21 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst | 2 |
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`. |