]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39877: PyGILState_Ensure() don't call PyEval_InitThreads() (GH-18891)
authorVictor Stinner <vstinner@python.org>
Mon, 9 Mar 2020 23:37:48 +0000 (00:37 +0100)
committerGitHub <noreply@github.com>
Mon, 9 Mar 2020 23:37:48 +0000 (00:37 +0100)
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.

Include/internal/pycore_ceval.h
Python/ceval.c
Python/pystate.c

index b20e85ccb0aa3a886d5921e8d2bf17d3cb44ee28..70ce0ee5f70d3412ad263f1175f6cc631b9f8dbf 100644 (file)
@@ -53,6 +53,7 @@ extern PyObject *_PyEval_EvalCode(
     PyObject *kwdefs, PyObject *closure,
     PyObject *name, PyObject *qualname);
 
+extern int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime);
 extern PyStatus _PyEval_InitThreads(PyThreadState *tstate);
 
 #ifdef __cplusplus
index 72a830468faa6f8cdb1a44450797b28328571b56..0ee740ace3d86c6c17457193473ac925fab787cd 100644 (file)
@@ -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
 PyEval_ThreadsInitialized(void)
 {
     _PyRuntimeState *runtime = &_PyRuntime;
-    return gil_created(&runtime->ceval.gil);
+    return _PyEval_ThreadsInitialized(runtime);
 }
 
 PyStatus
index f907fc1fc9a6a24a3b6c10c6551e313d232c5a25..a926e9753cb491f3c76b16a65bb217d8ee365d9b 100644 (file)
@@ -1280,27 +1280,28 @@ PyGILState_Check(void)
 PyGILState_STATE
 PyGILState_Ensure(void)
 {
-    struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
-    int current;
-    PyThreadState *tcur;
-    int need_init_threads = 0;
+    _PyRuntimeState *runtime = &_PyRuntime;
+    struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
 
     /* Note that we do not auto-init Python here - apart from
        potential races with 2 threads auto-initializing, pep-311
        spells out other issues.  Embedders are expected to have
-       called Py_Initialize() and usually PyEval_InitThreads().
-    */
-    /* Py_Initialize() hasn't been called! */
+       called Py_Initialize(). */
+
+    /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
+       called by Py_Initialize() */
+    assert(_PyEval_ThreadsInitialized(runtime));
     assert(gilstate->autoInterpreterState);
 
-    tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
+    PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
+    int current;
     if (tcur == NULL) {
-        need_init_threads = 1;
-
-        /* Create a new thread state for this thread */
+        /* Create a new Python thread state for this thread */
         tcur = PyThreadState_New(gilstate->autoInterpreterState);
-        if (tcur == NULL)
+        if (tcur == NULL) {
             Py_FatalError("Couldn't create thread-state for new thread");
+        }
+
         /* This is our thread state!  We'll need to delete it in the
            matching call to PyGILState_Release(). */
         tcur->gilstate_counter = 0;
@@ -1321,13 +1322,6 @@ PyGILState_Ensure(void)
     */
     ++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;
 }