bpo-31516: current_thread() should not return a dummy thread at shutdown (#3673)
bpo-31516: current_thread() should not return a dummy thread at shutdown
This commit is contained in:
parent
e6f62f69f0
commit
1023dbbcb7
|
@ -547,6 +547,35 @@ class ThreadTests(BaseTestCase):
|
||||||
self.assertEqual(err, b"")
|
self.assertEqual(err, b"")
|
||||||
self.assertEqual(data, "Thread-1\nTrue\nTrue\n")
|
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):
|
def test_tstate_lock(self):
|
||||||
# Test an implementation detail of Thread objects.
|
# Test an implementation detail of Thread objects.
|
||||||
started = _thread.allocate_lock()
|
started = _thread.allocate_lock()
|
||||||
|
|
|
@ -1158,8 +1158,8 @@ class Timer(Thread):
|
||||||
self.function(*self.args, **self.kwargs)
|
self.function(*self.args, **self.kwargs)
|
||||||
self.finished.set()
|
self.finished.set()
|
||||||
|
|
||||||
|
|
||||||
# Special thread class to represent the main thread
|
# Special thread class to represent the main thread
|
||||||
# This is garbage collected through an exit handler
|
|
||||||
|
|
||||||
class _MainThread(Thread):
|
class _MainThread(Thread):
|
||||||
|
|
||||||
|
@ -1272,7 +1272,6 @@ def _shutdown():
|
||||||
while t:
|
while t:
|
||||||
t.join()
|
t.join()
|
||||||
t = _pickSomeNonDaemonThread()
|
t = _pickSomeNonDaemonThread()
|
||||||
_main_thread._delete()
|
|
||||||
|
|
||||||
def _pickSomeNonDaemonThread():
|
def _pickSomeNonDaemonThread():
|
||||||
for t in enumerate():
|
for t in enumerate():
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
``threading.current_thread()`` should not return a dummy thread at shutdown.
|
Loading…
Reference in New Issue