mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
Issue #18808: Non-daemon threads are now automatically joined when a sub-interpreter is shutdown (it would previously dump a fatal error).
This commit is contained in:
parent
0bb766b95c
commit
7eaf3f7080
3 changed files with 54 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
_thread = import_module('_thread')
|
_thread = import_module('_thread')
|
||||||
threading = import_module('threading')
|
threading = import_module('threading')
|
||||||
|
import _testcapi
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import weakref
|
import weakref
|
||||||
|
|
@ -754,6 +755,53 @@ class ThreadJoinOnShutdown(BaseTestCase):
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
|
class SubinterpThreadingTests(BaseTestCase):
|
||||||
|
|
||||||
|
def test_threads_join(self):
|
||||||
|
# Non-daemon threads should be joined at subinterpreter shutdown
|
||||||
|
# (issue #18808)
|
||||||
|
r, w = os.pipe()
|
||||||
|
self.addCleanup(os.close, r)
|
||||||
|
self.addCleanup(os.close, w)
|
||||||
|
code = r"""if 1:
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
def f():
|
||||||
|
# Sleep a bit so that the thread is still running when
|
||||||
|
# Py_EndInterpreter is called.
|
||||||
|
time.sleep(0.05)
|
||||||
|
os.write(%d, b"x")
|
||||||
|
threading.Thread(target=f).start()
|
||||||
|
""" % (w,)
|
||||||
|
ret = _testcapi.run_in_subinterp(code)
|
||||||
|
self.assertEqual(ret, 0)
|
||||||
|
# The thread was joined properly.
|
||||||
|
self.assertEqual(os.read(r, 1), b"x")
|
||||||
|
|
||||||
|
def test_daemon_threads_fatal_error(self):
|
||||||
|
subinterp_code = r"""if 1:
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
def f():
|
||||||
|
# Make sure the daemon thread is still running when
|
||||||
|
# Py_EndInterpreter is called.
|
||||||
|
time.sleep(10)
|
||||||
|
threading.Thread(target=f, daemon=True).start()
|
||||||
|
"""
|
||||||
|
script = r"""if 1:
|
||||||
|
import _testcapi
|
||||||
|
|
||||||
|
_testcapi.run_in_subinterp(%r)
|
||||||
|
""" % (subinterp_code,)
|
||||||
|
rc, out, err = assert_python_failure("-c", script)
|
||||||
|
self.assertIn("Fatal Python error: Py_EndInterpreter: "
|
||||||
|
"not the last thread", err.decode())
|
||||||
|
|
||||||
|
|
||||||
class ThreadingExceptionTests(BaseTestCase):
|
class ThreadingExceptionTests(BaseTestCase):
|
||||||
# A RuntimeError should be raised if Thread.start() is called
|
# A RuntimeError should be raised if Thread.start() is called
|
||||||
# multiple times.
|
# multiple times.
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ Projected Release date: 2013-09-08
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #18808: Non-daemon threads are now automatically joined when
|
||||||
|
a sub-interpreter is shutdown (it would previously dump a fatal error).
|
||||||
|
|
||||||
- Remove supporting for compiling on systems without getcwd().
|
- Remove supporting for compiling on systems without getcwd().
|
||||||
|
|
||||||
- Issue #18774: Remove last bits of GNU PTH thread code and thread_pth.h.
|
- Issue #18774: Remove last bits of GNU PTH thread code and thread_pth.h.
|
||||||
|
|
|
||||||
|
|
@ -789,6 +789,9 @@ Py_EndInterpreter(PyThreadState *tstate)
|
||||||
Py_FatalError("Py_EndInterpreter: thread is not current");
|
Py_FatalError("Py_EndInterpreter: thread is not current");
|
||||||
if (tstate->frame != NULL)
|
if (tstate->frame != NULL)
|
||||||
Py_FatalError("Py_EndInterpreter: thread still has a frame");
|
Py_FatalError("Py_EndInterpreter: thread still has a frame");
|
||||||
|
|
||||||
|
wait_for_thread_shutdown();
|
||||||
|
|
||||||
if (tstate != interp->tstate_head || tstate->next != NULL)
|
if (tstate != interp->tstate_head || tstate->next != NULL)
|
||||||
Py_FatalError("Py_EndInterpreter: not the last thread");
|
Py_FatalError("Py_EndInterpreter: not the last thread");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue