Skip to content

Commit

Permalink
pythongh-105182: Remove PyEval_AcquireLock() and PyEval_InitThreads() (
Browse files Browse the repository at this point in the history
…python#105183)

Remove functions in the C API:

* PyEval_AcquireLock()
* PyEval_ReleaseLock()
* PyEval_InitThreads()
* PyEval_ThreadsInitialized()

But keep these functions in the stable ABI.

Mention "make regen-limited-abi" in "make regen-all".
  • Loading branch information
vstinner authored Jun 1, 2023
1 parent 9ab587b commit ec0082c
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 105 deletions.
75 changes: 1 addition & 74 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ The following functions can be safely called before Python is initialized:
:c:func:`Py_Initialize`: :c:func:`Py_EncodeLocale`, :c:func:`Py_GetPath`,
:c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`,
:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome`,
:c:func:`Py_GetProgramName` and :c:func:`PyEval_InitThreads`.
and :c:func:`Py_GetProgramName`.


.. _global-conf-vars:
Expand Down Expand Up @@ -326,7 +326,6 @@ Initializing and finalizing the interpreter
.. c:function:: void Py_Initialize()
.. index::
single: PyEval_InitThreads()
single: modules (in module sys)
single: path (in module sys)
pair: module; builtins
Expand Down Expand Up @@ -813,45 +812,6 @@ code, or when embedding the Python interpreter:
this thread's interpreter state.
.. c:function:: void PyEval_InitThreads()
.. index::
single: PyEval_AcquireThread()
single: PyEval_ReleaseThread()
single: PyEval_SaveThread()
single: PyEval_RestoreThread()
Deprecated function which does nothing.
In Python 3.6 and older, this function created the GIL if it didn't exist.
.. versionchanged:: 3.9
The function now does nothing.
.. versionchanged:: 3.7
This function is now called by :c:func:`Py_Initialize()`, so you don't
have to call it yourself anymore.
.. versionchanged:: 3.2
This function cannot be called before :c:func:`Py_Initialize()` anymore.
.. deprecated:: 3.9
.. index:: pair: module; _thread
.. c:function:: int PyEval_ThreadsInitialized()
Returns a non-zero value if :c:func:`PyEval_InitThreads` has been called. This
function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded.
.. versionchanged:: 3.7
The :term:`GIL` is now initialized by :c:func:`Py_Initialize()`.
.. deprecated:: 3.9
.. c:function:: PyThreadState* PyEval_SaveThread()
Release the global interpreter lock (if it has been created) and reset the
Expand Down Expand Up @@ -1223,39 +1183,6 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
available (even when threads have not been initialized).
.. c:function:: void PyEval_AcquireLock()
Acquire the global interpreter lock. The lock must have been created earlier.
If this thread already has the lock, a deadlock ensues.
.. deprecated:: 3.2
This function does not update the current thread state. Please use
:c:func:`PyEval_RestoreThread` or :c:func:`PyEval_AcquireThread`
instead.
.. note::
Calling this function from a thread when the runtime is finalizing
will terminate the thread, even if the thread was not created by Python.
You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to
check if the interpreter is in process of being finalized before calling
this function to avoid unwanted termination.
.. versionchanged:: 3.8
Updated to be consistent with :c:func:`PyEval_RestoreThread`,
:c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`,
and terminate the current thread if called while the interpreter is finalizing.
.. c:function:: void PyEval_ReleaseLock()
Release the global interpreter lock. The lock must have been created earlier.
.. deprecated:: 3.2
This function does not update the current thread state. Please use
:c:func:`PyEval_SaveThread` or :c:func:`PyEval_ReleaseThread`
instead.
.. _sub-interpreter-support:
Sub-interpreter support
Expand Down
6 changes: 0 additions & 6 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,6 @@ PyErr_WarnFormat::...::
PyErr_WriteUnraisable:void:::
PyErr_WriteUnraisable:PyObject*:obj:0:

PyEval_AcquireLock:void:::

PyEval_AcquireThread:void:::
PyEval_AcquireThread:PyThreadState*:tstate::

Expand All @@ -783,10 +781,6 @@ PyEval_GetFuncDesc:PyObject*:func:0:
PyEval_GetFuncName:const char*:::
PyEval_GetFuncName:PyObject*:func:0:

PyEval_InitThreads:void:::

PyEval_ReleaseLock:void:::

PyEval_ReleaseThread:void:::
PyEval_ReleaseThread:PyThreadState*:tstate::

Expand Down
4 changes: 0 additions & 4 deletions Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,19 @@ Removed
Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization
Configuration <init-config>` instead (:pep:`587`), added to Python 3.8.
(Contributed by Victor Stinner in :gh:`105145`.)

* Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()``
functions, deprecated in Python 3.9. Since Python 3.7, ``Py_Initialize()``
always creates the GIL: calling ``PyEval_InitThreads()`` did nothing and
``PyEval_ThreadsInitialized()`` always returned non-zero.
(Contributed by Victor Stinner in :gh:`105182`.)

* Remove ``PyEval_AcquireLock()`` and ``PyEval_ReleaseLock()`` functions,
deprecated in Python 3.2. They didn't update the current thread state.
They can be replaced with:

* :c:func:`PyEval_SaveThread` and :c:func:`PyEval_RestoreThread`;
* low-level :c:func:`PyEval_AcquireThread` and :c:func:`PyEval_RestoreThread`;
* or :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.

(Contributed by Victor Stinner in :gh:`105182`.)
8 changes: 0 additions & 8 deletions Include/ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,6 @@ PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);

Py_DEPRECATED(3.9) PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
/* PyEval_AcquireLock() and PyEval_ReleaseLock() are part of stable ABI.
* They will be removed from this header file in the future version.
* But they will be remained in ABI until Python 4.0.
*/
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void);
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_ReleaseLock(void);
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);

Expand Down
3 changes: 2 additions & 1 deletion Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,8 @@ regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \
regen-pegen-metaparser regen-pegen regen-test-frozenmain \
regen-test-levenshtein regen-global-objects
@echo
@echo "Note: make regen-stdlib-module-names and make regen-configure should be run manually"
@echo "Note: make regen-stdlib-module-names, make regen-limited-abi"
@echo "and make regen-configure should be run manually"

############################################################################
# Special rules for object files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()``
functions, deprecated in Python 3.9. Patch by Victor Stinner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove ``PyEval_AcquireLock()`` and ``PyEval_ReleaseLock()`` functions,
deprecated in Python 3.2. Patch by Victor Stinner.
4 changes: 4 additions & 0 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@
added = '3.2'
[function.PyEval_AcquireLock]
added = '3.2'
abi_only = true
[function.PyEval_AcquireThread]
added = '3.2'
[function.PyEval_CallFunction]
Expand Down Expand Up @@ -697,8 +698,10 @@
added = '3.2'
[function.PyEval_InitThreads]
added = '3.2'
abi_only = true
[function.PyEval_ReleaseLock]
added = '3.2'
abi_only = true
[function.PyEval_ReleaseThread]
added = '3.2'
[function.PyEval_RestoreThread]
Expand All @@ -707,6 +710,7 @@
added = '3.2'
[function.PyEval_ThreadsInitialized]
added = '3.2'
abi_only = true
[data.PyExc_ArithmeticError]
added = '3.2'
[data.PyExc_AssertionError]
Expand Down
8 changes: 0 additions & 8 deletions Misc/valgrind-python.supp
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,6 @@
# Will need to fix that.
#

{
Suppress leaking the GIL. Happens once per process, see comment in ceval.c.
Memcheck:Leak
fun:malloc
fun:PyThread_allocate_lock
fun:PyEval_InitThreads
}

{
Suppress leaking the GIL after a fork.
Memcheck:Leak
Expand Down
13 changes: 9 additions & 4 deletions Python/ceval_gil.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ _PyEval_ThreadsInitialized(void)
return gil_created(gil);
}

int
// Function removed in the Python 3.13 API but kept in the stable ABI.
PyAPI_FUNC(int)
PyEval_ThreadsInitialized(void)
{
return _PyEval_ThreadsInitialized();
Expand Down Expand Up @@ -584,7 +585,8 @@ _PyEval_FiniGIL(PyInterpreterState *interp)
interp->ceval.gil = NULL;
}

void
// Function removed in the Python 3.13 API but kept in the stable ABI.
PyAPI_FUNC(void)
PyEval_InitThreads(void)
{
/* Do nothing: kept for backward compatibility */
Expand All @@ -597,7 +599,9 @@ _PyEval_Fini(void)
_Py_PrintSpecializationStats(1);
#endif
}
void

// Function removed in the Python 3.13 API but kept in the stable ABI.
PyAPI_FUNC(void)
PyEval_AcquireLock(void)
{
PyThreadState *tstate = _PyThreadState_GET();
Expand All @@ -606,7 +610,8 @@ PyEval_AcquireLock(void)
take_gil(tstate);
}

void
// Function removed in the Python 3.13 API but kept in the stable ABI.
PyAPI_FUNC(void)
PyEval_ReleaseLock(void)
{
PyThreadState *tstate = _PyThreadState_GET();
Expand Down

0 comments on commit ec0082c

Please sign in to comment.