From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Mon, 27 Sep 2021 12:49:30 +0000 (-0700) Subject: bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532) X-Git-Tag: v3.9.8~127 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ecb641b887af2feb026a266e2fceedee0815ca8;p=thirdparty%2FPython%2Fcpython.git bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532) 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 a22be4943c119fecf5433d999227ff78fc2e5741) Co-authored-by: Victor Stinner --- diff --git a/Lib/threading.py b/Lib/threading.py index a49775e6b177..1c98b3b2cdf4 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -1064,11 +1064,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): diff --git a/Misc/NEWS.d/next/Library/2021-09-23-22-17-26.bpo-45274.gPpa4E.rst b/Misc/NEWS.d/next/Library/2021-09-23-22-17-26.bpo-45274.gPpa4E.rst new file mode 100644 index 000000000000..94d06cef89b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-23-22-17-26.bpo-45274.gPpa4E.rst @@ -0,0 +1,5 @@ +Fix a race condition in the :meth:`Thread.join() ` +method of the :mod:`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. Patch by Victor +Stinner.