mirror of
https://github.com/python/cpython.git
synced 2025-07-28 13:44:43 +00:00
bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532) (GH-28580)
Fix a race condition in the Thread.join() method of the threading
module. If the function is interrupted by a signal and the signal
handler raises an exception, make sure that the thread remains in a
consistent state to prevent a deadlock.
(cherry picked from commit a22be4943c
)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
d452b2963b
commit
fae2694bea
2 changed files with 22 additions and 4 deletions
|
@ -1100,11 +1100,24 @@ class Thread:
|
|||
# If the lock is acquired, the C code is done, and self._stop() is
|
||||
# called. That sets ._is_stopped to True, and ._tstate_lock to None.
|
||||
lock = self._tstate_lock
|
||||
if lock is None: # already determined that the C code is done
|
||||
if lock is None:
|
||||
# already determined that the C code is done
|
||||
assert self._is_stopped
|
||||
elif lock.acquire(block, timeout):
|
||||
lock.release()
|
||||
self._stop()
|
||||
return
|
||||
|
||||
try:
|
||||
if lock.acquire(block, timeout):
|
||||
lock.release()
|
||||
self._stop()
|
||||
except:
|
||||
if lock.locked():
|
||||
# bpo-45274: lock.acquire() acquired the lock, but the function
|
||||
# was interrupted with an exception before reaching the
|
||||
# lock.release(). It can happen if a signal handler raises an
|
||||
# exception, like CTRL+C which raises KeyboardInterrupt.
|
||||
lock.release()
|
||||
self._stop()
|
||||
raise
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue