From bea1c70144e4de97312e9d04dd4c90e549f79f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 4 Jan 2007 21:06:57 +0000 Subject: [PATCH] Bug #1566280: Explicitly invoke threading._shutdown from Py_Main, to avoid relying on atexit. --- Lib/threading.py | 10 +++++----- Misc/NEWS | 3 +++ Modules/main.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Lib/threading.py b/Lib/threading.py index 5655dded32d..fecd3cc3041 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -636,13 +636,11 @@ class _MainThread(Thread): _active_limbo_lock.acquire() _active[_get_ident()] = self _active_limbo_lock.release() - import atexit - atexit.register(self.__exitfunc) def _set_daemon(self): return False - def __exitfunc(self): + def _exitfunc(self): self._Thread__stop() t = _pickSomeNonDaemonThread() if t: @@ -715,9 +713,11 @@ def enumerate(): from thread import stack_size -# Create the main thread object +# Create the main thread object, +# and make it available for the interpreter +# (Py_Main) as threading._shutdown. -_MainThread() +_shutdown = _MainThread()._exitfunc # get thread-local implementation, either from the thread # module, or from the python fallback diff --git a/Misc/NEWS b/Misc/NEWS index aab3e4372ca..74af3e4c1d0 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.5.1c1? Core and builtins ----------------- +- Bug #1566280: Explicitly invoke threading._shutdown from Py_Main, + to avoid relying on atexit. + - Bug #1590891: random.randrange don't return correct value for big number - Bug #1456209: In some obscure cases it was possible for a class with a diff --git a/Modules/main.c b/Modules/main.c index ac5f96e62fc..83d567fede1 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -176,6 +176,33 @@ static int RunModule(char *module) return 0; } +/* Wait until threading._shutdown completes, provided + the threading module was imported in the first place. + The shutdown routine will wait until all non-daemon + "threading" threads have completed. */ +#include "abstract.h" +static void +WaitForThreadShutdown() +{ +#ifdef WITH_THREAD + PyObject *result; + PyThreadState *tstate = PyThreadState_GET(); + PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, + "threading"); + if (threading == NULL) { + /* threading not imported */ + PyErr_Clear(); + return; + } + result = PyObject_CallMethod(threading, "_shutdown", ""); + if (result == NULL) + PyErr_WriteUnraisable(threading); + else + Py_DECREF(result); + Py_DECREF(threading); +#endif +} + /* Main program */ int @@ -513,6 +540,8 @@ Py_Main(int argc, char **argv) /* XXX */ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; + WaitForThreadShutdown(); + Py_Finalize(); #ifdef RISCOS if (Py_RISCOSWimpFlag)