cpython: 4ceca79d1c63 (original) (raw)
Mercurial > cpython
changeset 93526:4ceca79d1c63 2.7
Issue #21963: backout issue #1856 patch (avoid crashes and lockups when daemon threads run while the interpreter is shutting down; instead, these threads are now killed when they try to take the GIL), as it seems to break some existing code. [#21963]
Antoine Pitrou solipsis@pitrou.net | |
---|---|
date | Fri, 21 Nov 2014 02:04:21 +0100 |
parents | 8bc29f5ebeff |
children | c9b4dc1ab7ae |
files | Include/pythonrun.h Lib/test/test_threading.py Misc/NEWS Python/ceval.c Python/pythonrun.c Python/thread_pthread.h |
diffstat | 6 files changed, 8 insertions(+), 71 deletions(-)[+] [-] Include/pythonrun.h 2 Lib/test/test_threading.py 43 Misc/NEWS 9 Python/ceval.c 12 Python/pythonrun.c 9 Python/thread_pthread.h 4 |
line wrap: on
line diff
--- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -147,8 +147,6 @@ PyAPI_FUNC(void) PyOS_FiniInterrupts(voi PyAPI_FUNC(void) PyByteArray_Fini(void); PyAPI_FUNC(void) _PyRandom_Fini(void); -PyAPI_DATA(PyThreadState ) _Py_Finalizing; - / Stuff with no proper home (yet) */ PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *); PyAPI_DATA(int) (*PyOS_InputHook)(void);
--- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -700,49 +700,6 @@ class ThreadJoinOnShutdown(BaseTestCase) output = "end of worker thread\nend of main thread\n" self.assertScriptHasOutput(script, output)
- @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
- def test_6_daemon_threads(self):
# Check that a daemon thread cannot crash the interpreter on shutdown[](#l2.9)
# by manipulating internal structures that are being disposed of in[](#l2.10)
# the main thread.[](#l2.11)
script = """if True:[](#l2.12)
import os[](#l2.13)
import random[](#l2.14)
import sys[](#l2.15)
import time[](#l2.16)
import threading[](#l2.17)
thread_has_run = set()[](#l2.19)
def random_io():[](#l2.21)
'''Loop for a while sleeping random tiny amounts and doing some I/O.'''[](#l2.22)
while True:[](#l2.23)
in_f = open(os.__file__, 'rb')[](#l2.24)
stuff = in_f.read(200)[](#l2.25)
null_f = open(os.devnull, 'wb')[](#l2.26)
null_f.write(stuff)[](#l2.27)
time.sleep(random.random() / 1995)[](#l2.28)
null_f.close()[](#l2.29)
in_f.close()[](#l2.30)
thread_has_run.add(threading.current_thread())[](#l2.31)
def main():[](#l2.33)
count = 0[](#l2.34)
for _ in range(40):[](#l2.35)
new_thread = threading.Thread(target=random_io)[](#l2.36)
new_thread.daemon = True[](#l2.37)
new_thread.start()[](#l2.38)
count += 1[](#l2.39)
while len(thread_has_run) < count:[](#l2.40)
time.sleep(0.001)[](#l2.41)
# Trigger process shutdown[](#l2.42)
sys.exit(0)[](#l2.43)
main()[](#l2.45)
"""[](#l2.46)
rc, out, err = assert_python_ok('-c', script)[](#l2.47)
self.assertFalse(err)[](#l2.48)
- @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") def test_reinit_tls_after_fork(self):
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,11 @@ What's New in Python 2.7.9? Core and Builtins ----------------- +- Backout issue #1856 patch (avoid crashes and lockups when daemon threads
- run while the interpreter is shutting down; instead, these threads are
- now killed when they try to take the GIL), as it seems to break some
- existing code. +
- Issue #22604: Fix assertion error in debug mode when dividing a complex number by (nan+0j). @@ -360,10 +365,6 @@ Core and Builtins
- Issue #21831: Avoid integer overflow when large sizes and offsets are given to the buffer type. CVE-2014-7185. -- Issue #1856: Avoid crashes and lockups when daemon threads run while the
- interpreter is shutting down; instead, these threads are now killed when they
- try to take the GIL. -
- Issue #19656: Running Python with the -3 option now also warns about non-ascii bytes literals.
--- a/Python/ceval.c +++ b/Python/ceval.c @@ -355,12 +355,6 @@ PyEval_RestoreThread(PyThreadState *tsta if (interpreter_lock) { int err = errno; PyThread_acquire_lock(interpreter_lock, 1);
/* _Py_Finalizing is protected by the GIL */[](#l4.7)
if (_Py_Finalizing && tstate != _Py_Finalizing) {[](#l4.8)
PyThread_release_lock(interpreter_lock);[](#l4.9)
PyThread_exit_thread();[](#l4.10)
assert(0); /* unreachable */[](#l4.11)
}}[](#l4.12) errno = err;[](#l4.13)
#endif @@ -1025,12 +1019,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int PyThread_acquire_lock(interpreter_lock, 1);
/* Check if we should make a quick exit. */[](#l4.20)
if (_Py_Finalizing && _Py_Finalizing != tstate) {[](#l4.21)
PyThread_release_lock(interpreter_lock);[](#l4.22)
PyThread_exit_thread();[](#l4.23)
}[](#l4.24)
- if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate");
--- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -91,8 +91,6 @@ int _Py_QnewFlag = 0; int Py_NoUserSiteDirectory = 0; /* for -s and site.py / int Py_HashRandomizationFlag = 0; / for -R and PYTHONHASHSEED */ -PyThreadState _Py_Finalizing = NULL; - / Hack to force loading of object files / int (_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = [](#l5.11) @@ -165,7 +163,6 @@ Py_InitializeEx(int install_sigs) if (initialized) return; initialized = 1;
if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') Py_DebugFlag = add_flag(Py_DebugFlag, p); @@ -425,16 +422,12 @@ Py_Finalize(void) * the threads created via Threading. */ call_sys_exitfunc();
/* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp;
- /* Remaining threads (e.g. daemon threads) will automatically exit
after taking the GIL (in PyEval_RestoreThread()). */[](#l5.31)
- _Py_Finalizing = tstate;
- initialized = 0;
- /* Disable signal handling */ PyOS_FiniInterrupts();
--- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -242,9 +242,9 @@ void PyThread_exit_thread(void) { dprintf(("PyThread_exit_thread called\n"));