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:
Antoine Pitrou 2013-08-25 19:48:18 +02:00
parent 0bb766b95c
commit 7eaf3f7080
3 changed files with 54 additions and 0 deletions

View File

@ -9,6 +9,7 @@ import re
import sys
_thread = import_module('_thread')
threading = import_module('threading')
import _testcapi
import time
import unittest
import weakref
@ -754,6 +755,53 @@ class ThreadJoinOnShutdown(BaseTestCase):
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):
# A RuntimeError should be raised if Thread.start() is called
# multiple times.

View File

@ -10,6 +10,9 @@ Projected Release date: 2013-09-08
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().
- Issue #18774: Remove last bits of GNU PTH thread code and thread_pth.h.

View File

@ -789,6 +789,9 @@ Py_EndInterpreter(PyThreadState *tstate)
Py_FatalError("Py_EndInterpreter: thread is not current");
if (tstate->frame != NULL)
Py_FatalError("Py_EndInterpreter: thread still has a frame");
wait_for_thread_shutdown();
if (tstate != interp->tstate_head || tstate->next != NULL)
Py_FatalError("Py_EndInterpreter: not the last thread");