bpo-33608: Factor out a private, per-interpreter _Py_AddPendingCall(). (gh-13714)

This commit is contained in:
Eric Snow 2019-06-01 15:39:46 -06:00 committed by GitHub
parent 218e47b618
commit 6a150bcaeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 320 additions and 186 deletions

View file

@ -1147,15 +1147,31 @@ Py_FinalizeEx(void)
return status;
}
/* Get current thread state and interpreter pointer */
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
PyInterpreterState *interp = tstate->interp;
// Wrap up existing "threading"-module-created, non-daemon threads.
wait_for_thread_shutdown();
// Make any remaining pending calls.
_Py_FinishPendingCalls(runtime);
/* Get current thread state and interpreter pointer */
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
PyInterpreterState *interp = tstate->interp;
/* XXX For the moment we are going to ignore lingering pending calls.
* We've seen sporadic on some of the buildbots during finalization
* with the changes for per-interpreter pending calls (see bpo-33608),
* meaning the previous _PyEval_FinishPendincCalls() call here is
* a trigger, if not responsible.
*
* Ignoring pending calls at this point in the runtime lifecycle
* is okay (for now) for the following reasons:
*
* * pending calls are still not a widely-used feature
* * this only affects runtime finalization, where the process is
* likely to end soon anyway (except for some embdding cases)
*
* See bpo-37127 about resolving the problem. Ultimately the call
* here should be re-enabled.
*/
//_PyEval_FinishPendingCalls(interp);
/* The interpreter is still entirely intact at this point, and the
* exit funcs may be relying on that. In particular, if some thread
@ -1580,6 +1596,9 @@ Py_EndInterpreter(PyThreadState *tstate)
// Wrap up existing "threading"-module-created, non-daemon threads.
wait_for_thread_shutdown();
// Make any remaining pending calls.
_PyEval_FinishPendingCalls(interp);
call_py_exitfuncs(interp);
if (tstate != interp->tstate_head || tstate->next != NULL)