]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Bug #1566280: Explicitly invoke threading._shutdown from Py_Main,
authorMartin v. Löwis <martin@v.loewis.de>
Thu, 4 Jan 2007 21:06:57 +0000 (21:06 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Thu, 4 Jan 2007 21:06:57 +0000 (21:06 +0000)
to avoid relying on atexit.

Lib/threading.py
Misc/NEWS
Modules/main.c

index 5655dded32d1679d39ddc83d939800f040cf809d..fecd3cc3041a2c0c405f09dfea9acac30b66b190 100644 (file)
@@ -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
index aab3e4372cae6d37347689544ec0591d8288fbe4..74af3e4c1d05e91a8e0f481d680039ed231b75fc 100644 (file)
--- 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
index ac5f96e62fc74c734242cd204e855b5341daa572..83d567fede1c035dfa79df798b5a1ce2f1529e35 100644 (file)
@@ -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, "<stdin>", &cf) != 0;
 
+       WaitForThreadShutdown();
+
        Py_Finalize();
 #ifdef RISCOS
        if (Py_RISCOSWimpFlag)