Skip to content

Commit be6b74c

Browse files
authored
bpo-20891: Fix PyGILState_Ensure() (#4650) (#4657)
When PyGILState_Ensure() is called in a non-Python thread before PyEval_InitThreads(), only call PyEval_InitThreads() after calling PyThreadState_New() to fix a crash. (cherry picked from commit b4d1e1f)
1 parent 7d1cfee commit be6b74c

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix PyGILState_Ensure(). When PyGILState_Ensure() is called in a non-Python
2+
thread before PyEval_InitThreads(), only call PyEval_InitThreads() after
3+
calling PyThreadState_New() to fix a crash.

Python/pystate.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@ PyGILState_Ensure(void)
588588
{
589589
int current;
590590
PyThreadState *tcur;
591+
int need_init_threads = 0;
592+
591593
/* Note that we do not auto-init Python here - apart from
592594
potential races with 2 threads auto-initializing, pep-311
593595
spells out other issues. Embedders are expected to have
@@ -596,6 +598,8 @@ PyGILState_Ensure(void)
596598
assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
597599
tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
598600
if (tcur == NULL) {
601+
need_init_threads = 1;
602+
599603
/* Create a new thread state for this thread */
600604
tcur = PyThreadState_New(autoInterpreterState);
601605
if (tcur == NULL)
@@ -605,16 +609,28 @@ PyGILState_Ensure(void)
605609
tcur->gilstate_counter = 0;
606610
current = 0; /* new thread state is never current */
607611
}
608-
else
612+
else {
609613
current = PyThreadState_IsCurrent(tcur);
610-
if (current == 0)
614+
}
615+
616+
if (current == 0) {
611617
PyEval_RestoreThread(tcur);
618+
}
619+
612620
/* Update our counter in the thread-state - no need for locks:
613621
- tcur will remain valid as we hold the GIL.
614622
- the counter is safe as we are the only thread "allowed"
615623
to modify this value
616624
*/
617625
++tcur->gilstate_counter;
626+
627+
if (need_init_threads) {
628+
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
629+
called from a new thread for the first time, we need the create the
630+
GIL. */
631+
PyEval_InitThreads();
632+
}
633+
618634
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
619635
}
620636

0 commit comments

Comments
 (0)