mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Bug #128475: mimetools.encode (sometimes) fails when called from a thread.
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.
This commit is contained in:
parent
eccd02a40d
commit
384fd106e8
2 changed files with 11 additions and 3 deletions
|
@ -16,9 +16,8 @@ def _run_exitfuncs():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
while _exithandlers:
|
while _exithandlers:
|
||||||
func, targs, kargs = _exithandlers[-1]
|
func, targs, kargs = _exithandlers.pop()
|
||||||
apply(func, targs, kargs)
|
apply(func, targs, kargs)
|
||||||
_exithandlers.remove(_exithandlers[-1])
|
|
||||||
|
|
||||||
def register(func, *targs, **kargs):
|
def register(func, *targs, **kargs):
|
||||||
"""register a function to be executed upon normal program termination
|
"""register a function to be executed upon normal program termination
|
||||||
|
|
|
@ -181,9 +181,18 @@ Py_Finalize(void)
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
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();
|
call_sys_exitfunc();
|
||||||
|
initialized = 0;
|
||||||
|
|
||||||
/* Get current thread state and interpreter pointer */
|
/* Get current thread state and interpreter pointer */
|
||||||
tstate = PyThreadState_Get();
|
tstate = PyThreadState_Get();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue