From eed520784531cde9db2c04e0457b274e0dfd99f0 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 30 Sep 2014 00:37:19 -0700 Subject: [PATCH] python27: Remove avoid daemon thread shutdown #i21963 --- .../interpreters/python/2.7/default.nix | 3 + .../remove-avoid-daemon-thread-shutdown.patch | 170 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 pkgs/development/interpreters/python/2.7/remove-avoid-daemon-thread-shutdown.patch diff --git a/pkgs/development/interpreters/python/2.7/default.nix b/pkgs/development/interpreters/python/2.7/default.nix index cf1d4bdc8da..b8539d8e64a 100644 --- a/pkgs/development/interpreters/python/2.7/default.nix +++ b/pkgs/development/interpreters/python/2.7/default.nix @@ -28,6 +28,9 @@ let # patch python to put zero timestamp into pyc # if DETERMINISTIC_BUILD env var is set ./deterministic-build.patch + + # http://bugs.python.org/issue21963 + ./remove-avoid-daemon-thread-shutdown.patch ]; postPatch = stdenv.lib.optionalString (stdenv.gcc.libc != null) '' diff --git a/pkgs/development/interpreters/python/2.7/remove-avoid-daemon-thread-shutdown.patch b/pkgs/development/interpreters/python/2.7/remove-avoid-daemon-thread-shutdown.patch new file mode 100644 index 00000000000..650f276f08a --- /dev/null +++ b/pkgs/development/interpreters/python/2.7/remove-avoid-daemon-thread-shutdown.patch @@ -0,0 +1,170 @@ +changeset: 93046:61ad2208a5ce +branch: 2.7 +tag: tip +user: William A. Kennington III +date: Mon Oct 13 13:57:12 2014 -0700 +summary: Revert: 91229:7741d0dd66ca to fix i21963 + +diff -r ed4098380799 -r 61ad2208a5ce Include/pythonrun.h +--- a/Include/pythonrun.h Mon Oct 13 12:58:03 2014 -0700 ++++ b/Include/pythonrun.h Mon Oct 13 13:57:12 2014 -0700 +@@ -147,8 +147,6 @@ + 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); +diff -r ed4098380799 -r 61ad2208a5ce Lib/test/test_threading.py +--- a/Lib/test/test_threading.py Mon Oct 13 12:58:03 2014 -0700 ++++ b/Lib/test/test_threading.py Mon Oct 13 13:57:12 2014 -0700 +@@ -700,49 +700,6 @@ + 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 +- # by manipulating internal structures that are being disposed of in +- # the main thread. +- script = """if True: +- import os +- import random +- import sys +- import time +- import threading +- +- thread_has_run = set() +- +- def random_io(): +- '''Loop for a while sleeping random tiny amounts and doing some I/O.''' +- while True: +- in_f = open(os.__file__, 'rb') +- stuff = in_f.read(200) +- null_f = open(os.devnull, 'wb') +- null_f.write(stuff) +- time.sleep(random.random() / 1995) +- null_f.close() +- in_f.close() +- thread_has_run.add(threading.current_thread()) +- +- def main(): +- count = 0 +- for _ in range(40): +- new_thread = threading.Thread(target=random_io) +- new_thread.daemon = True +- new_thread.start() +- count += 1 +- while len(thread_has_run) < count: +- time.sleep(0.001) +- # Trigger process shutdown +- sys.exit(0) +- +- main() +- """ +- rc, out, err = assert_python_ok('-c', script) +- self.assertFalse(err) +- + @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): +diff -r ed4098380799 -r 61ad2208a5ce Misc/NEWS +--- a/Misc/NEWS Mon Oct 13 12:58:03 2014 -0700 ++++ b/Misc/NEWS Mon Oct 13 13:57:12 2014 -0700 +@@ -96,10 +96,6 @@ + - Issue #21831: Avoid integer overflow when large sizes and offsets are given to + the buffer type. + +-- 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. + +diff -r ed4098380799 -r 61ad2208a5ce Python/ceval.c +--- a/Python/ceval.c Mon Oct 13 12:58:03 2014 -0700 ++++ b/Python/ceval.c Mon Oct 13 13:57:12 2014 -0700 +@@ -355,12 +355,6 @@ + if (interpreter_lock) { + int err = errno; + PyThread_acquire_lock(interpreter_lock, 1); +- /* _Py_Finalizing is protected by the GIL */ +- if (_Py_Finalizing && tstate != _Py_Finalizing) { +- PyThread_release_lock(interpreter_lock); +- PyThread_exit_thread(); +- assert(0); /* unreachable */ +- } + errno = err; + } + #endif +@@ -1024,13 +1018,6 @@ + /* Other threads may run now */ + + PyThread_acquire_lock(interpreter_lock, 1); +- +- /* Check if we should make a quick exit. */ +- if (_Py_Finalizing && _Py_Finalizing != tstate) { +- PyThread_release_lock(interpreter_lock); +- PyThread_exit_thread(); +- } +- + if (PyThreadState_Swap(tstate) != NULL) + Py_FatalError("ceval: orphan tstate"); + +diff -r ed4098380799 -r 61ad2208a5ce Python/pythonrun.c +--- a/Python/pythonrun.c Mon Oct 13 12:58:03 2014 -0700 ++++ b/Python/pythonrun.c Mon Oct 13 13:57:12 2014 -0700 +@@ -91,8 +91,6 @@ + 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) = \ +@@ -165,7 +163,6 @@ + if (initialized) + return; + initialized = 1; +- _Py_Finalizing = NULL; + + if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = add_flag(Py_DebugFlag, p); +@@ -425,16 +422,12 @@ + * the threads created via Threading. + */ + call_sys_exitfunc(); ++ initialized = 0; + + /* 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()). */ +- _Py_Finalizing = tstate; +- initialized = 0; +- + /* Disable signal handling */ + PyOS_FiniInterrupts(); + +diff -r ed4098380799 -r 61ad2208a5ce Python/thread_pthread.h +--- a/Python/thread_pthread.h Mon Oct 13 12:58:03 2014 -0700 ++++ b/Python/thread_pthread.h Mon Oct 13 13:57:12 2014 -0700 +@@ -242,9 +242,9 @@ + PyThread_exit_thread(void) + { + dprintf(("PyThread_exit_thread called\n")); +- if (!initialized) ++ if (!initialized) { + exit(0); +- pthread_exit(0); ++ } + } + + #ifdef USE_SEMAPHORES +