bpo-39877: PyGILState_Ensure() don't call PyEval_InitThreads() (GH-18891)
PyGILState_Ensure() doesn't call PyEval_InitThreads() anymore when a new Python thread state is created. The GIL is created by Py_Initialize() since Python 3.7, it's not needed to call PyEval_InitThreads() explicitly. Add an assertion to ensure that the GIL is already created.
This commit is contained in:
parent
addaaaa946
commit
175a704abf
|
@ -53,6 +53,7 @@ extern PyObject *_PyEval_EvalCode(
|
||||||
PyObject *kwdefs, PyObject *closure,
|
PyObject *kwdefs, PyObject *closure,
|
||||||
PyObject *name, PyObject *qualname);
|
PyObject *name, PyObject *qualname);
|
||||||
|
|
||||||
|
extern int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime);
|
||||||
extern PyStatus _PyEval_InitThreads(PyThreadState *tstate);
|
extern PyStatus _PyEval_InitThreads(PyThreadState *tstate);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -198,11 +198,17 @@ ensure_tstate_not_null(const char *func, PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyEval_ThreadsInitialized(_PyRuntimeState *runtime)
|
||||||
|
{
|
||||||
|
return gil_created(&runtime->ceval.gil);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PyEval_ThreadsInitialized(void)
|
PyEval_ThreadsInitialized(void)
|
||||||
{
|
{
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
return gil_created(&runtime->ceval.gil);
|
return _PyEval_ThreadsInitialized(runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyStatus
|
PyStatus
|
||||||
|
|
|
@ -1280,27 +1280,28 @@ PyGILState_Check(void)
|
||||||
PyGILState_STATE
|
PyGILState_STATE
|
||||||
PyGILState_Ensure(void)
|
PyGILState_Ensure(void)
|
||||||
{
|
{
|
||||||
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
int current;
|
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
|
||||||
PyThreadState *tcur;
|
|
||||||
int need_init_threads = 0;
|
|
||||||
|
|
||||||
/* Note that we do not auto-init Python here - apart from
|
/* Note that we do not auto-init Python here - apart from
|
||||||
potential races with 2 threads auto-initializing, pep-311
|
potential races with 2 threads auto-initializing, pep-311
|
||||||
spells out other issues. Embedders are expected to have
|
spells out other issues. Embedders are expected to have
|
||||||
called Py_Initialize() and usually PyEval_InitThreads().
|
called Py_Initialize(). */
|
||||||
*/
|
|
||||||
/* Py_Initialize() hasn't been called! */
|
/* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
|
||||||
|
called by Py_Initialize() */
|
||||||
|
assert(_PyEval_ThreadsInitialized(runtime));
|
||||||
assert(gilstate->autoInterpreterState);
|
assert(gilstate->autoInterpreterState);
|
||||||
|
|
||||||
tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
|
PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
|
||||||
|
int current;
|
||||||
if (tcur == NULL) {
|
if (tcur == NULL) {
|
||||||
need_init_threads = 1;
|
/* Create a new Python thread state for this thread */
|
||||||
|
|
||||||
/* Create a new thread state for this thread */
|
|
||||||
tcur = PyThreadState_New(gilstate->autoInterpreterState);
|
tcur = PyThreadState_New(gilstate->autoInterpreterState);
|
||||||
if (tcur == NULL)
|
if (tcur == NULL) {
|
||||||
Py_FatalError("Couldn't create thread-state for new thread");
|
Py_FatalError("Couldn't create thread-state for new thread");
|
||||||
|
}
|
||||||
|
|
||||||
/* This is our thread state! We'll need to delete it in the
|
/* This is our thread state! We'll need to delete it in the
|
||||||
matching call to PyGILState_Release(). */
|
matching call to PyGILState_Release(). */
|
||||||
tcur->gilstate_counter = 0;
|
tcur->gilstate_counter = 0;
|
||||||
|
@ -1321,13 +1322,6 @@ PyGILState_Ensure(void)
|
||||||
*/
|
*/
|
||||||
++tcur->gilstate_counter;
|
++tcur->gilstate_counter;
|
||||||
|
|
||||||
if (need_init_threads) {
|
|
||||||
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
|
|
||||||
called from a new thread for the first time, we need the create the
|
|
||||||
GIL. */
|
|
||||||
PyEval_InitThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
|
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue