bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532) · python/cpython@a22be49 (original) (raw)

Original file line number Diff line number Diff line change
@@ -1094,11 +1094,24 @@ def _wait_for_tstate_lock(self, block=True, timeout=-1):
1094 1094 # If the lock is acquired, the C code is done, and self._stop() is
1095 1095 # called. That sets ._is_stopped to True, and ._tstate_lock to None.
1096 1096 lock = self._tstate_lock
1097 -if lock is None: # already determined that the C code is done
1097 +if lock is None:
1098 +# already determined that the C code is done
1098 1099 assert self._is_stopped
1099 -elif lock.acquire(block, timeout):
1100 -lock.release()
1101 -self._stop()
1100 +return
1101 +
1102 +try:
1103 +if lock.acquire(block, timeout):
1104 +lock.release()
1105 +self._stop()
1106 +except:
1107 +if lock.locked():
1108 +# bpo-45274: lock.acquire() acquired the lock, but the function
1109 +# was interrupted with an exception before reaching the
1110 +# lock.release(). It can happen if a signal handler raises an
1111 +# exception, like CTRL+C which raises KeyboardInterrupt.
1112 +lock.release()
1113 +self._stop()
1114 +raise
1102 1115
1103 1116 @property
1104 1117 def name(self):