mirror of
https://github.com/python/cpython.git
synced 2026-04-13 23:31:02 +00:00
gh-125053: Document that ob_mutex must only be used via critical section API (#144599)
Add a warning in the free-threading extensions howto explaining that PyObject.ob_mutex is reserved for the critical section API and must not be locked directly with PyMutex_Lock, as this can cause deadlocks. Extension authors who need their own lock should add a separate PyMutex field to their object struct. Also add an ob_mutex member entry under PyObject in the C API reference (Doc/c-api/structures.rst) with a cross-reference to the howto. Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
2756d56eef
commit
bf4017b161
2 changed files with 37 additions and 0 deletions
|
|
@ -48,6 +48,19 @@ under :ref:`reference counting <countingrefs>`.
|
|||
Do not use this field directly; use :c:macro:`Py_TYPE` and
|
||||
:c:func:`Py_SET_TYPE` instead.
|
||||
|
||||
.. c:member:: PyMutex ob_mutex
|
||||
|
||||
A :ref:`per-object lock <per-object-locks>`, present only in the :term:`free-threaded <free threading>`
|
||||
build (when :c:macro:`Py_GIL_DISABLED` is defined).
|
||||
|
||||
This field is **reserved for use by the critical section API**
|
||||
(:c:macro:`Py_BEGIN_CRITICAL_SECTION` / :c:macro:`Py_END_CRITICAL_SECTION`).
|
||||
Do **not** lock it directly with ``PyMutex_Lock``; doing so can cause
|
||||
deadlocks. If you need your own lock, add a separate :c:type:`PyMutex`
|
||||
field to your object struct.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
|
||||
.. c:type:: PyVarObject
|
||||
|
||||
|
|
|
|||
|
|
@ -384,6 +384,30 @@ Important Considerations
|
|||
internal extension state, standard mutexes or other synchronization
|
||||
primitives might be more appropriate.
|
||||
|
||||
.. _per-object-locks:
|
||||
|
||||
Per-Object Locks (``ob_mutex``)
|
||||
...............................
|
||||
|
||||
In the free-threaded build, each Python object contains a :c:member:`~PyObject.ob_mutex`
|
||||
field of type :c:type:`PyMutex`. This mutex is **reserved for use by the
|
||||
critical section API** (:c:macro:`Py_BEGIN_CRITICAL_SECTION` /
|
||||
:c:macro:`Py_END_CRITICAL_SECTION`).
|
||||
|
||||
.. warning::
|
||||
|
||||
Do **not** lock ``ob_mutex`` directly with ``PyMutex_Lock(&obj->ob_mutex)``.
|
||||
Mixing direct ``PyMutex_Lock`` calls with the critical section API on the
|
||||
same mutex can cause deadlocks.
|
||||
|
||||
Even if your own code never uses critical sections on a particular object type,
|
||||
**CPython internals may use the critical section API on any Python object**.
|
||||
|
||||
If your extension type needs its own lock, add a separate :c:type:`PyMutex`
|
||||
field (or another synchronization primitive) to your object struct.
|
||||
:c:type:`PyMutex` is very lightweight, so there is negligible cost to having
|
||||
an additional one.
|
||||
|
||||
|
||||
Building Extensions for the Free-Threaded Build
|
||||
===============================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue