mirror of
https://github.com/python/cpython.git
synced 2025-08-23 10:16:01 +00:00
gh-104690 Disallow thread creation and fork at interpreter finalization (#104826)
Disallow thread creation and fork at interpreter finalization. in the following functions, check if interpreter is finalizing and raise `RuntimeError` with appropriate message: * `_thread.start_new_thread` and thus `threading` * `posix.fork` * `posix.fork1` * `posix.forkpty` * `_posixsubprocess.fork_exec` when a `preexec_fn=` is supplied. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
This commit is contained in:
parent
eaff9c39aa
commit
ce558e69d4
8 changed files with 97 additions and 30 deletions
|
@ -531,34 +531,6 @@ class ThreadTests(BaseTestCase):
|
|||
t = threading.Thread(daemon=True)
|
||||
self.assertTrue(t.daemon)
|
||||
|
||||
@support.requires_fork()
|
||||
def test_fork_at_exit(self):
|
||||
# bpo-42350: Calling os.fork() after threading._shutdown() must
|
||||
# not log an error.
|
||||
code = textwrap.dedent("""
|
||||
import atexit
|
||||
import os
|
||||
import sys
|
||||
from test.support import wait_process
|
||||
|
||||
# Import the threading module to register its "at fork" callback
|
||||
import threading
|
||||
|
||||
def exit_handler():
|
||||
pid = os.fork()
|
||||
if not pid:
|
||||
print("child process ok", file=sys.stderr, flush=True)
|
||||
# child process
|
||||
else:
|
||||
wait_process(pid, exitcode=0)
|
||||
|
||||
# exit_handler() will be called after threading._shutdown()
|
||||
atexit.register(exit_handler)
|
||||
""")
|
||||
_, out, err = assert_python_ok("-c", code)
|
||||
self.assertEqual(out, b'')
|
||||
self.assertEqual(err.rstrip(), b'child process ok')
|
||||
|
||||
@support.requires_fork()
|
||||
def test_dummy_thread_after_fork(self):
|
||||
# Issue #14308: a dummy thread in the active list doesn't mess up
|
||||
|
@ -1048,6 +1020,22 @@ class ThreadTests(BaseTestCase):
|
|||
self.assertEqual(out, b'')
|
||||
self.assertEqual(err, b'')
|
||||
|
||||
def test_start_new_thread_at_exit(self):
|
||||
code = """if 1:
|
||||
import atexit
|
||||
import _thread
|
||||
|
||||
def f():
|
||||
print("shouldn't be printed")
|
||||
|
||||
def exit_handler():
|
||||
_thread.start_new_thread(f, ())
|
||||
|
||||
atexit.register(exit_handler)
|
||||
"""
|
||||
_, out, err = assert_python_ok("-c", code)
|
||||
self.assertEqual(out, b'')
|
||||
self.assertIn(b"can't create new thread at interpreter shutdown", err)
|
||||
|
||||
class ThreadJoinOnShutdown(BaseTestCase):
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue