diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-06-13 10:06:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-13 10:06:24 (GMT) |
commit | 6f75c873752a16a7ad8f35855b1e29f59d048e84 (patch) | |
tree | c3df13f3339045c40d4335c64a8e37c3774c3b99 /Lib | |
parent | b4b814b3988abf69f07f8492d82e855c51b2a75d (diff) | |
download | cpython-6f75c873752a16a7ad8f35855b1e29f59d048e84.zip cpython-6f75c873752a16a7ad8f35855b1e29f59d048e84.tar.gz cpython-6f75c873752a16a7ad8f35855b1e29f59d048e84.tar.bz2 |
tbpo-36402: Fix threading.Thread._stop() (GH-14047)
Remove the _tstate_lock from _shutdown_locks, don't remove None.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_threading.py | 24 | ||||
-rw-r--r-- | Lib/threading.py | 2 |
2 files changed, 25 insertions, 1 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index ad90010..0a0a62b 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -738,6 +738,30 @@ class ThreadTests(BaseTestCase): finally: sys.settrace(old_trace) + @cpython_only + def test_shutdown_locks(self): + for daemon in (False, True): + with self.subTest(daemon=daemon): + event = threading.Event() + thread = threading.Thread(target=event.wait, daemon=daemon) + + # Thread.start() must add lock to _shutdown_locks, + # but only for non-daemon thread + thread.start() + tstate_lock = thread._tstate_lock + if not daemon: + self.assertIn(tstate_lock, threading._shutdown_locks) + else: + self.assertNotIn(tstate_lock, threading._shutdown_locks) + + # unblock the thread and join it + event.set() + thread.join() + + # Thread._stop() must remove tstate_lock from _shutdown_locks. + # Daemon threads must never add it to _shutdown_locks. + self.assertNotIn(tstate_lock, threading._shutdown_locks) + class ThreadJoinOnShutdown(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py index 6792640..7c6d404 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -965,7 +965,7 @@ class Thread: self._tstate_lock = None if not self.daemon: with _shutdown_locks_lock: - _shutdown_locks.discard(self._tstate_lock) + _shutdown_locks.discard(lock) def _delete(self): "Remove current thread from the dict of currently running threads." |