bpo-36356: Destroy the GIL at exit (GH-12453)

* Add _PyEval_FiniThreads2(). _PyEval_FiniThreads() now only clears
  the pending lock, whereas _PyEval_FiniThreads2() destroys the GIL.
* pymain_free() now calls _PyEval_FiniThreads2().
* Py_FinalizeEx() now calls _PyEval_FiniThreads().
This commit is contained in:
Victor Stinner 2019-04-29 11:15:56 +02:00 committed by GitHub
parent 7a5a1cfe04
commit b36e5d627d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 18 deletions

View file

@ -4,8 +4,9 @@
#include "Python-ast.h"
#undef Yield /* undefine macro conflicting with <winbase.h> */
#include "pycore_coreconfig.h"
#include "pycore_ceval.h" /* _PyEval_FiniThreads() */
#include "pycore_context.h"
#include "pycore_coreconfig.h"
#include "pycore_fileutils.h"
#include "pycore_hamt.h"
#include "pycore_pathconfig.h"
@ -555,12 +556,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
return _Py_INIT_ERR("can't make first thread");
(void) PyThreadState_Swap(tstate);
/* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because
destroying the GIL might fail when it is being referenced from
another running thread (see issue #9901).
/* Destroying the GIL in Py_FinalizeEx might fail when it is being
referenced from another running thread (see bpo-9901).
Instead we destroy the previously created GIL here, which ensures
that we can call Py_Initialize / Py_FinalizeEx multiple times. */
_PyEval_FiniThreads();
_PyEval_FiniThreads2();
/* Auto-thread-state API */
_PyGILState_Init(runtime, interp, tstate);
@ -1357,6 +1357,7 @@ Py_FinalizeEx(void)
call_ll_exitfuncs(runtime);
_PyEval_FiniThreads();
_PyRuntime_Finalize();
return status;
}