diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2017-10-02 15:20:01 (GMT) |
---|---|---|
committer | Antoine Pitrou <pitrou@free.fr> | 2017-10-02 15:20:01 (GMT) |
commit | ac6245a31f9a757db0520722c592cb7fdcb55eb0 (patch) | |
tree | a20a85df675e6b29d07c1e137d55c652c557d21a | |
parent | 66fb5ef3bb9e36187a0e5052dfd99899447df671 (diff) | |
download | cpython-ac6245a31f9a757db0520722c592cb7fdcb55eb0.zip cpython-ac6245a31f9a757db0520722c592cb7fdcb55eb0.tar.gz cpython-ac6245a31f9a757db0520722c592cb7fdcb55eb0.tar.bz2 |
[3.6] bpo-31516: current_thread() should not return a dummy thread at shutdown (GH-3673) (#3856)
bpo-31516: current_thread() should not return a dummy thread at shutdown
(cherry picked from commit 1023dbbcb7f05e76053486ae7ef7f73b4cdc5398)
-rw-r--r-- | Lib/test/test_threading.py | 29 | ||||
-rw-r--r-- | Lib/threading.py | 3 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2017-09-20-18-43-01.bpo-31516.23Yuq3.rst | 1 |
3 files changed, 31 insertions, 2 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 9cadc0f..b42314f 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -542,6 +542,35 @@ class ThreadTests(BaseTestCase): self.assertEqual(err, b"") self.assertEqual(data, "Thread-1\nTrue\nTrue\n") + def test_main_thread_during_shutdown(self): + # bpo-31516: current_thread() should still point to the main thread + # at shutdown + code = """if 1: + import gc, threading + + main_thread = threading.current_thread() + assert main_thread is threading.main_thread() # sanity check + + class RefCycle: + def __init__(self): + self.cycle = self + + def __del__(self): + print("GC:", + threading.current_thread() is main_thread, + threading.main_thread() is main_thread, + threading.enumerate() == [main_thread]) + + RefCycle() + gc.collect() # sanity check + x = RefCycle() + """ + _, out, err = assert_python_ok("-c", code) + data = out.decode() + self.assertEqual(err, b"") + self.assertEqual(data.splitlines(), + ["GC: True True True"] * 2) + def test_tstate_lock(self): # Test an implementation detail of Thread objects. started = _thread.allocate_lock() diff --git a/Lib/threading.py b/Lib/threading.py index 95978d3..bb25565 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -1182,8 +1182,8 @@ class Timer(Thread): self.function(*self.args, **self.kwargs) self.finished.set() + # Special thread class to represent the main thread -# This is garbage collected through an exit handler class _MainThread(Thread): @@ -1293,7 +1293,6 @@ def _shutdown(): while t: t.join() t = _pickSomeNonDaemonThread() - _main_thread._delete() def _pickSomeNonDaemonThread(): for t in enumerate(): diff --git a/Misc/NEWS.d/next/Library/2017-09-20-18-43-01.bpo-31516.23Yuq3.rst b/Misc/NEWS.d/next/Library/2017-09-20-18-43-01.bpo-31516.23Yuq3.rst new file mode 100644 index 0000000..af48d15 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-09-20-18-43-01.bpo-31516.23Yuq3.rst @@ -0,0 +1 @@ +``threading.current_thread()`` should not return a dummy thread at shutdown. |