Skip to content

Commit 175a704

Browse files
authored
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.
1 parent addaaaa commit 175a704

File tree

3 files changed

+21
-20
lines changed

3 files changed

+21
-20
lines changed

Include/internal/pycore_ceval.h

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ extern PyObject *_PyEval_EvalCode(
5353
PyObject *kwdefs, PyObject *closure,
5454
PyObject *name, PyObject *qualname);
5555

56+
extern int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime);
5657
extern PyStatus _PyEval_InitThreads(PyThreadState *tstate);
5758

5859
#ifdef __cplusplus

Python/ceval.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,17 @@ ensure_tstate_not_null(const char *func, PyThreadState *tstate)
198198
}
199199

200200

201+
int
202+
_PyEval_ThreadsInitialized(_PyRuntimeState *runtime)
203+
{
204+
return gil_created(&runtime->ceval.gil);
205+
}
206+
201207
int
202208
PyEval_ThreadsInitialized(void)
203209
{
204210
_PyRuntimeState *runtime = &_PyRuntime;
205-
return gil_created(&runtime->ceval.gil);
211+
return _PyEval_ThreadsInitialized(runtime);
206212
}
207213

208214
PyStatus

Python/pystate.c

+13-19
Original file line numberDiff line numberDiff line change
@@ -1280,27 +1280,28 @@ PyGILState_Check(void)
12801280
PyGILState_STATE
12811281
PyGILState_Ensure(void)
12821282
{
1283-
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
1284-
int current;
1285-
PyThreadState *tcur;
1286-
int need_init_threads = 0;
1283+
_PyRuntimeState *runtime = &_PyRuntime;
1284+
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
12871285

12881286
/* Note that we do not auto-init Python here - apart from
12891287
potential races with 2 threads auto-initializing, pep-311
12901288
spells out other issues. Embedders are expected to have
1291-
called Py_Initialize() and usually PyEval_InitThreads().
1292-
*/
1293-
/* Py_Initialize() hasn't been called! */
1289+
called Py_Initialize(). */
1290+
1291+
/* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
1292+
called by Py_Initialize() */
1293+
assert(_PyEval_ThreadsInitialized(runtime));
12941294
assert(gilstate->autoInterpreterState);
12951295

1296-
tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
1296+
PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
1297+
int current;
12971298
if (tcur == NULL) {
1298-
need_init_threads = 1;
1299-
1300-
/* Create a new thread state for this thread */
1299+
/* Create a new Python thread state for this thread */
13011300
tcur = PyThreadState_New(gilstate->autoInterpreterState);
1302-
if (tcur == NULL)
1301+
if (tcur == NULL) {
13031302
Py_FatalError("Couldn't create thread-state for new thread");
1303+
}
1304+
13041305
/* This is our thread state! We'll need to delete it in the
13051306
matching call to PyGILState_Release(). */
13061307
tcur->gilstate_counter = 0;
@@ -1321,13 +1322,6 @@ PyGILState_Ensure(void)
13211322
*/
13221323
++tcur->gilstate_counter;
13231324

1324-
if (need_init_threads) {
1325-
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
1326-
called from a new thread for the first time, we need the create the
1327-
GIL. */
1328-
PyEval_InitThreads();
1329-
}
1330-
13311325
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
13321326
}
13331327

0 commit comments

Comments
 (0)