diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-25 17:48:18 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-25 17:48:18 (GMT) |
commit | 7eaf3f7080a0b0e1e551d2d9d2dcddd54d53af59 (patch) | |
tree | a2f3078056ba9c1e132603385ea9bc4f379032cb /Lib/test/test_threading.py | |
parent | 0bb766b95cc672a82d29fbe339e515b921f1bfcc (diff) | |
download | cpython-7eaf3f7080a0b0e1e551d2d9d2dcddd54d53af59.zip cpython-7eaf3f7080a0b0e1e551d2d9d2dcddd54d53af59.tar.gz cpython-7eaf3f7080a0b0e1e551d2d9d2dcddd54d53af59.tar.bz2 |
Issue #18808: Non-daemon threads are now automatically joined when a sub-interpreter is shutdown (it would previously dump a fatal error).
Diffstat (limited to 'Lib/test/test_threading.py')
-rw-r--r-- | Lib/test/test_threading.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index ecf22fc..3629749 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -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. |