Skip to content

Commit 2914bb3

Browse files
authored
bpo-20891: Py_Initialize() now creates the GIL (#4700)
The GIL is no longer created "on demand" to fix a race condition when PyGILState_Ensure() is called in a non-Python thread.
1 parent 8997f9c commit 2914bb3

File tree

4 files changed

+43
-52
lines changed

4 files changed

+43
-52
lines changed

Doc/c-api/init.rst

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -687,15 +687,14 @@ This is so common that a pair of macros exists to simplify it::
687687
688688
The :c:macro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a
689689
hidden local variable; the :c:macro:`Py_END_ALLOW_THREADS` macro closes the
690-
block. These two macros are still available when Python is compiled without
691-
thread support (they simply have an empty expansion).
690+
block.
692691
693-
When thread support is enabled, the block above expands to the following code::
692+
The block above expands to the following code::
694693
695694
PyThreadState *_save;
696695
697696
_save = PyEval_SaveThread();
698-
...Do some blocking I/O operation...
697+
... Do some blocking I/O operation ...
699698
PyEval_RestoreThread(_save);
700699
701700
.. index::
@@ -818,54 +817,40 @@ code, or when embedding the Python interpreter:
818817
819818
This is a no-op when called for a second time.
820819
820+
.. versionchanged:: 3.7
821+
This function is now called by :c:func:`Py_Initialize()`, so you don't
822+
have to call it yourself anymore.
823+
821824
.. versionchanged:: 3.2
822825
This function cannot be called before :c:func:`Py_Initialize()` anymore.
823826
824827
.. index:: module: _thread
825828
826-
.. note::
827-
828-
When only the main thread exists, no GIL operations are needed. This is a
829-
common situation (most Python programs do not use threads), and the lock
830-
operations slow the interpreter down a bit. Therefore, the lock is not
831-
created initially. This situation is equivalent to having acquired the lock:
832-
when there is only a single thread, all object accesses are safe. Therefore,
833-
when this function initializes the global interpreter lock, it also acquires
834-
it. Before the Python :mod:`_thread` module creates a new thread, knowing
835-
that either it has the lock or the lock hasn't been created yet, it calls
836-
:c:func:`PyEval_InitThreads`. When this call returns, it is guaranteed that
837-
the lock has been created and that the calling thread has acquired it.
838-
839-
It is **not** safe to call this function when it is unknown which thread (if
840-
any) currently has the global interpreter lock.
841-
842-
This function is not available when thread support is disabled at compile time.
843-
844829
845830
.. c:function:: int PyEval_ThreadsInitialized()
846831
847832
Returns a non-zero value if :c:func:`PyEval_InitThreads` has been called. This
848833
function can be called without holding the GIL, and therefore can be used to
849-
avoid calls to the locking API when running single-threaded. This function is
850-
not available when thread support is disabled at compile time.
834+
avoid calls to the locking API when running single-threaded.
835+
836+
.. versionchanged:: 3.7
837+
The :term:`GIL` is now initialized by :c:func:`Py_Initialize()`.
851838
852839
853840
.. c:function:: PyThreadState* PyEval_SaveThread()
854841
855842
Release the global interpreter lock (if it has been created and thread
856843
support is enabled) and reset the thread state to *NULL*, returning the
857844
previous thread state (which is not *NULL*). If the lock has been created,
858-
the current thread must have acquired it. (This function is available even
859-
when thread support is disabled at compile time.)
845+
the current thread must have acquired it.
860846
861847
862848
.. c:function:: void PyEval_RestoreThread(PyThreadState *tstate)
863849
864850
Acquire the global interpreter lock (if it has been created and thread
865851
support is enabled) and set the thread state to *tstate*, which must not be
866852
*NULL*. If the lock has been created, the current thread must not have
867-
acquired it, otherwise deadlock ensues. (This function is available even
868-
when thread support is disabled at compile time.)
853+
acquired it, otherwise deadlock ensues.
869854
870855
871856
.. c:function:: PyThreadState* PyThreadState_Get()
@@ -957,37 +942,37 @@ example usage in the Python source distribution.
957942
This macro expands to ``{ PyThreadState *_save; _save = PyEval_SaveThread();``.
958943
Note that it contains an opening brace; it must be matched with a following
959944
:c:macro:`Py_END_ALLOW_THREADS` macro. See above for further discussion of this
960-
macro. It is a no-op when thread support is disabled at compile time.
945+
macro.
961946
962947
963948
.. c:macro:: Py_END_ALLOW_THREADS
964949
965950
This macro expands to ``PyEval_RestoreThread(_save); }``. Note that it contains
966951
a closing brace; it must be matched with an earlier
967952
:c:macro:`Py_BEGIN_ALLOW_THREADS` macro. See above for further discussion of
968-
this macro. It is a no-op when thread support is disabled at compile time.
953+
this macro.
969954
970955
971956
.. c:macro:: Py_BLOCK_THREADS
972957
973958
This macro expands to ``PyEval_RestoreThread(_save);``: it is equivalent to
974-
:c:macro:`Py_END_ALLOW_THREADS` without the closing brace. It is a no-op when
975-
thread support is disabled at compile time.
959+
:c:macro:`Py_END_ALLOW_THREADS` without the closing brace.
976960
977961
978962
.. c:macro:: Py_UNBLOCK_THREADS
979963
980964
This macro expands to ``_save = PyEval_SaveThread();``: it is equivalent to
981965
:c:macro:`Py_BEGIN_ALLOW_THREADS` without the opening brace and variable
982-
declaration. It is a no-op when thread support is disabled at compile time.
966+
declaration.
983967
984968
985969
Low-level API
986970
-------------
987971
988-
All of the following functions are only available when thread support is enabled
989-
at compile time, and must be called only when the global interpreter lock has
990-
been created.
972+
All of the following functions must be called after :c:func:`Py_Initialize`.
973+
974+
.. versionchanged:: 3.7
975+
:c:func:`Py_Initialize()` now initializes the :term:`GIL`.
991976
992977
993978
.. c:function:: PyInterpreterState* PyInterpreterState_New()
@@ -1068,8 +1053,7 @@ been created.
10681053
If this thread already has the lock, deadlock ensues.
10691054
10701055
:c:func:`PyEval_RestoreThread` is a higher-level function which is always
1071-
available (even when thread support isn't enabled or when threads have
1072-
not been initialized).
1056+
available (even when threads have not been initialized).
10731057
10741058
10751059
.. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate)
@@ -1081,8 +1065,7 @@ been created.
10811065
reported.
10821066
10831067
:c:func:`PyEval_SaveThread` is a higher-level function which is always
1084-
available (even when thread support isn't enabled or when threads have
1085-
not been initialized).
1068+
available (even when threads have not been initialized).
10861069
10871070
10881071
.. c:function:: void PyEval_AcquireLock()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Py_Initialize() now creates the GIL. The GIL is no longer created "on demand"
2+
to fix a race condition when PyGILState_Ensure() is called in a non-Python
3+
thread.

Python/ceval.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ PyEval_SaveThread(void)
254254
PyThreadState *tstate = PyThreadState_Swap(NULL);
255255
if (tstate == NULL)
256256
Py_FatalError("PyEval_SaveThread: NULL tstate");
257-
if (gil_created())
258-
drop_gil(tstate);
257+
assert(gil_created());
258+
drop_gil(tstate);
259259
return tstate;
260260
}
261261

@@ -264,17 +264,18 @@ PyEval_RestoreThread(PyThreadState *tstate)
264264
{
265265
if (tstate == NULL)
266266
Py_FatalError("PyEval_RestoreThread: NULL tstate");
267-
if (gil_created()) {
268-
int err = errno;
269-
take_gil(tstate);
270-
/* _Py_Finalizing is protected by the GIL */
271-
if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) {
272-
drop_gil(tstate);
273-
PyThread_exit_thread();
274-
Py_UNREACHABLE();
275-
}
276-
errno = err;
267+
assert(gil_created());
268+
269+
int err = errno;
270+
take_gil(tstate);
271+
/* _Py_Finalizing is protected by the GIL */
272+
if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) {
273+
drop_gil(tstate);
274+
PyThread_exit_thread();
275+
Py_UNREACHABLE();
277276
}
277+
errno = err;
278+
278279
PyThreadState_Swap(tstate);
279280
}
280281

Python/pylifecycle.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,13 @@ _Py_InitializeCore(const _PyCoreConfig *core_config)
681681
Instead we destroy the previously created GIL here, which ensures
682682
that we can call Py_Initialize / Py_FinalizeEx multiple times. */
683683
_PyEval_FiniThreads();
684+
684685
/* Auto-thread-state API */
685686
_PyGILState_Init(interp, tstate);
686687

688+
/* Create the GIL */
689+
PyEval_InitThreads();
690+
687691
_Py_ReadyTypes();
688692

689693
if (!_PyFrame_Init())

0 commit comments

Comments
 (0)