]> granicus.if.org Git - python/commitdiff
[3.6] bpo-31516: current_thread() should not return a dummy thread at shutdown (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 2 Oct 2017 15:20:01 +0000 (08:20 -0700)
committerAntoine Pitrou <pitrou@free.fr>
Mon, 2 Oct 2017 15:20:01 +0000 (17:20 +0200)
bpo-31516: current_thread() should not return a dummy thread at shutdown
(cherry picked from commit 1023dbbcb7f05e76053486ae7ef7f73b4cdc5398)

Lib/test/test_threading.py
Lib/threading.py
Misc/NEWS.d/next/Library/2017-09-20-18-43-01.bpo-31516.23Yuq3.rst [new file with mode: 0644]

index 9cadc0f1c025a912e90c02f6febcad75b88d4bd6..b42314fdbb20d623f05b2bacd935827c82c905ad 100644 (file)
@@ -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()
index 95978d310a2f3aa9780248dac71d0b7bca113d37..bb2556544b07814608d0e6b23a70045139810ebd 100644 (file)
@@ -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 (file)
index 0000000..af48d15
--- /dev/null
@@ -0,0 +1 @@
+``threading.current_thread()`` should not return a dummy thread at shutdown.