]> granicus.if.org Git - python/commitdiff
Bug #128475: mimetools.encode (sometimes) fails when called from a thread.
authorTim Peters <tim.peters@gmail.com>
Sun, 21 Jan 2001 03:40:37 +0000 (03:40 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 21 Jan 2001 03:40:37 +0000 (03:40 +0000)
pythonrun.c:  In Py_Finalize, don't reset the initialized flag until after
the exit funcs have run.
atexit.py:  in _run_exitfuncs, mutate the list of pending calls in a
threadsafe way.  This wasn't a contributor to bug 128475, it just burned
my eyeballs when looking at that bug.

Lib/atexit.py
Python/pythonrun.c

index bcf7e548a033c2fcccfda9358fd1b906c5ade68c..61f2458dd0a429b653ac3546a6053fe80e36c402 100644 (file)
@@ -16,9 +16,8 @@ def _run_exitfuncs():
     """
 
     while _exithandlers:
-        func, targs, kargs = _exithandlers[-1]
+        func, targs, kargs = _exithandlers.pop()
         apply(func, targs, kargs)
-        _exithandlers.remove(_exithandlers[-1])
 
 def register(func, *targs, **kargs):
     """register a function to be executed upon normal program termination
index ff2142b807dbcca92c068f519a71645b0c0e5873..4c94f9b6a90874ebc3c026e8ada2076d7bb2ab8f 100644 (file)
@@ -181,9 +181,18 @@ Py_Finalize(void)
 
        if (!initialized)
                return;
-       initialized = 0;
 
+       /* The interpreter is still entirely intact at this point, and the
+        * exit funcs may be relying on that.  In particular, if some thread
+        * or exit func is still waiting to do an import, the import machinery
+        * expects Py_IsInitialized() to return true.  So don't say the
+        * interpreter is uninitialized until after the exit funcs have run.
+        * Note that Threading.py uses an exit func to do a join on all the
+        * threads created thru it, so this also protects pending imports in
+        * the threads created via Threading.
+        */
        call_sys_exitfunc();
+       initialized = 0;
 
        /* Get current thread state and interpreter pointer */
        tstate = PyThreadState_Get();