Skip to content

Commit 6f75c87

Browse files
authored
tbpo-36402: Fix threading.Thread._stop() (GH-14047)
Remove the _tstate_lock from _shutdown_locks, don't remove None.
1 parent b4b814b commit 6f75c87

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

Lib/test/test_threading.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,30 @@ def callback():
738738
finally:
739739
sys.settrace(old_trace)
740740

741+
@cpython_only
742+
def test_shutdown_locks(self):
743+
for daemon in (False, True):
744+
with self.subTest(daemon=daemon):
745+
event = threading.Event()
746+
thread = threading.Thread(target=event.wait, daemon=daemon)
747+
748+
# Thread.start() must add lock to _shutdown_locks,
749+
# but only for non-daemon thread
750+
thread.start()
751+
tstate_lock = thread._tstate_lock
752+
if not daemon:
753+
self.assertIn(tstate_lock, threading._shutdown_locks)
754+
else:
755+
self.assertNotIn(tstate_lock, threading._shutdown_locks)
756+
757+
# unblock the thread and join it
758+
event.set()
759+
thread.join()
760+
761+
# Thread._stop() must remove tstate_lock from _shutdown_locks.
762+
# Daemon threads must never add it to _shutdown_locks.
763+
self.assertNotIn(tstate_lock, threading._shutdown_locks)
764+
741765

742766
class ThreadJoinOnShutdown(BaseTestCase):
743767

Lib/threading.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ def _stop(self):
965965
self._tstate_lock = None
966966
if not self.daemon:
967967
with _shutdown_locks_lock:
968-
_shutdown_locks.discard(self._tstate_lock)
968+
_shutdown_locks.discard(lock)
969969

970970
def _delete(self):
971971
"Remove current thread from the dict of currently running threads."

0 commit comments

Comments
 (0)