bpo-43311: Create GIL autoTSSkey ealier (GH-24819)

At Python startup, call _PyGILState_Init() before
PyInterpreterState_New() which calls _PyThreadState_GET(). When
Python is built using --with-experimental-isolated-subinterpreters,
_PyThreadState_GET() uses autoTSSkey.
This commit is contained in:
Victor Stinner 2021-03-10 20:00:46 +01:00 committed by GitHub
parent 9a9c11ad41
commit 87f649a409
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 7 deletions

View file

@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
#include "pycore_runtime.h" // _PyRuntimeState
/* Forward declarations */ /* Forward declarations */
struct _PyArgv; struct _PyArgv;
struct pyruntimestate; struct pyruntimestate;
@ -88,7 +90,8 @@ extern void _PyWarnings_Fini(PyInterpreterState *interp);
extern void _PyAST_Fini(PyInterpreterState *interp); extern void _PyAST_Fini(PyInterpreterState *interp);
extern void _PyAtExit_Fini(PyInterpreterState *interp); extern void _PyAtExit_Fini(PyInterpreterState *interp);
extern PyStatus _PyGILState_Init(PyThreadState *tstate); extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime);
extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate);
extern void _PyGILState_Fini(PyInterpreterState *interp); extern void _PyGILState_Fini(PyInterpreterState *interp);
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp);

View file

@ -577,7 +577,7 @@ init_interp_create_gil(PyThreadState *tstate)
_PyEval_FiniGIL(tstate->interp); _PyEval_FiniGIL(tstate->interp);
/* Auto-thread-state API */ /* Auto-thread-state API */
status = _PyGILState_Init(tstate); status = _PyGILState_SetTstate(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
@ -597,12 +597,19 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
const PyConfig *config, const PyConfig *config,
PyThreadState **tstate_p) PyThreadState **tstate_p)
{ {
/* Auto-thread-state API */
PyStatus status = _PyGILState_Init(runtime);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
PyInterpreterState *interp = PyInterpreterState_New(); PyInterpreterState *interp = PyInterpreterState_New();
if (interp == NULL) { if (interp == NULL) {
return _PyStatus_ERR("can't make main interpreter"); return _PyStatus_ERR("can't make main interpreter");
} }
assert(_Py_IsMainInterpreter(interp));
PyStatus status = _PyConfig_Copy(&interp->config, config); status = _PyConfig_Copy(&interp->config, config);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }

View file

@ -1327,7 +1327,21 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
Py_Initialize/Py_FinalizeEx Py_Initialize/Py_FinalizeEx
*/ */
PyStatus PyStatus
_PyGILState_Init(PyThreadState *tstate) _PyGILState_Init(_PyRuntimeState *runtime)
{
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
return _PyStatus_NO_MEMORY();
}
// PyThreadState_New() calls _PyGILState_NoteThreadState() which does
// nothing before autoInterpreterState is set.
assert(gilstate->autoInterpreterState == NULL);
return _PyStatus_OK();
}
PyStatus
_PyGILState_SetTstate(PyThreadState *tstate)
{ {
if (!_Py_IsMainInterpreter(tstate->interp)) { if (!_Py_IsMainInterpreter(tstate->interp)) {
/* Currently, PyGILState is shared by all interpreters. The main /* Currently, PyGILState is shared by all interpreters. The main
@ -1341,9 +1355,6 @@ _PyGILState_Init(PyThreadState *tstate)
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
return _PyStatus_NO_MEMORY();
}
gilstate->autoInterpreterState = tstate->interp; gilstate->autoInterpreterState = tstate->interp;
assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL);
assert(tstate->gilstate_counter == 0); assert(tstate->gilstate_counter == 0);