]> granicus.if.org Git - python/commitdiff
Bug #1566280: Explicitly invoke threading._shutdown from Py_Main,
authorMartin v. Löwis <martin@v.loewis.de>
Thu, 4 Jan 2007 21:06:12 +0000 (21:06 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Thu, 4 Jan 2007 21:06:12 +0000 (21:06 +0000)
to avoid relying on atexit.
Will backport to 2.5.

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 4f310d8796ee4ed1a44700b39d796ca0c7a670d4..972f1e0a32d08b8943e305f2482e1aed6b97f543 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
 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
 
 - Patch #1586791: Better exception messages for some operations on strings,
index 2224dfe2f0486c73e12bb93cf364886bc4e9085f..dc46d550c6e22641e57c223429a9dfbb4f482967 100644 (file)
@@ -177,6 +177,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
@@ -514,6 +541,8 @@ Py_Main(int argc, char **argv)
                /* XXX */
                sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
 
+       WaitForThreadShutdown();
+
        Py_Finalize();
 #ifdef RISCOS
        if (Py_RISCOSWimpFlag)