]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-134009: Expose `PyMutex_IsLocked` in the public C API (gh-134365)
authorSam Gross <colesbury@gmail.com>
Tue, 1 Jul 2025 17:26:13 +0000 (13:26 -0400)
committerGitHub <noreply@github.com>
Tue, 1 Jul 2025 17:26:13 +0000 (13:26 -0400)
The `PyMutex_IsLocked()` function is useful in assertions for verifying
that code maintains certain locking invariants.

Doc/c-api/init.rst
Doc/whatsnew/3.15.rst
Include/cpython/lock.h
Include/internal/pycore_lock.h
Misc/NEWS.d/next/C_API/2025-05-20-17-13-51.gh-issue-134009.CpCmry.rst [new file with mode: 0644]
Python/lock.c

index 41fd4ea14ef12f22f93286921f2de7451fa2af94..409539dec17d73724ffa6097ce1e7c0fc103843c 100644 (file)
@@ -2277,6 +2277,18 @@ The C-API provides a basic mutual exclusion lock.
 
    .. versionadded:: 3.13
 
+.. c:function:: int PyMutex_IsLocked(PyMutex *m)
+
+   Returns non-zero if the mutex *m* is currently locked, zero otherwise.
+
+   .. note::
+
+      This function is intended for use in assertions and debugging only and
+      should not be used to make concurrency control decisions, as the lock
+      state may change immediately after the check.
+
+   .. versionadded:: next
+
 .. _python-critical-section-api:
 
 Python Critical Section API
index df636dc9051f0dcc3120be1388a4ff101d8a0243..f06d4c84ea53d1118d682284a79603a23efdcdcd 100644 (file)
@@ -346,6 +346,13 @@ Porting to Python 3.15
 
   (Contributed by Serhiy Storchaka in :gh:`133595`.)
 
+* Private functions promoted to public C APIs:
+
+  * ``PyMutex_IsLocked()`` : :c:func:`PyMutex_IsLocked`
+
+  The |pythoncapi_compat_project| can be used to get most of these new
+  functions on Python 3.14 and older.
+
 Deprecated C APIs
 -----------------
 
index 8ee03e82f74dfdc747a6af65b3baf7f3095792b7..63886fca28eae24ac903a5267ffd03c8d2e469b7 100644 (file)
@@ -36,6 +36,9 @@ PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m);
 // exported function for unlocking the mutex
 PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m);
 
+// exported function for checking if the mutex is locked
+PyAPI_FUNC(int) PyMutex_IsLocked(PyMutex *m);
+
 // Locks the mutex.
 //
 // If the mutex is currently locked, the calling thread will be parked until
@@ -61,3 +64,11 @@ _PyMutex_Unlock(PyMutex *m)
     }
 }
 #define PyMutex_Unlock _PyMutex_Unlock
+
+// Checks if the mutex is currently locked.
+static inline int
+_PyMutex_IsLocked(PyMutex *m)
+{
+    return (_Py_atomic_load_uint8(&m->_bits) & _Py_LOCKED) != 0;
+}
+#define PyMutex_IsLocked _PyMutex_IsLocked
index bd6011b60ac09a841beabe14af9cc8a283791cbc..585120108cf342e00f2c3b611cc9ead69dd5ae41 100644 (file)
@@ -25,13 +25,6 @@ PyMutex_LockFast(PyMutex *m)
     return _Py_atomic_compare_exchange_uint8(lock_bits, &expected, _Py_LOCKED);
 }
 
-// Checks if the mutex is currently locked.
-static inline int
-PyMutex_IsLocked(PyMutex *m)
-{
-    return (_Py_atomic_load_uint8(&m->_bits) & _Py_LOCKED) != 0;
-}
-
 // Re-initializes the mutex after a fork to the unlocked state.
 static inline void
 _PyMutex_at_fork_reinit(PyMutex *m)
diff --git a/Misc/NEWS.d/next/C_API/2025-05-20-17-13-51.gh-issue-134009.CpCmry.rst b/Misc/NEWS.d/next/C_API/2025-05-20-17-13-51.gh-issue-134009.CpCmry.rst
new file mode 100644 (file)
index 0000000..f060f09
--- /dev/null
@@ -0,0 +1 @@
+Expose :c:func:`PyMutex_IsLocked` as part of the public C API.
index eb09019e0a236d8e8fdcb06b85b80b617728ff15..a49d587a1686d953a5cb113a5dd051db1f3f4beb 100644 (file)
@@ -634,3 +634,11 @@ PyMutex_Unlock(PyMutex *m)
         Py_FatalError("unlocking mutex that is not locked");
     }
 }
+
+
+#undef PyMutex_IsLocked
+int
+PyMutex_IsLocked(PyMutex *m)
+{
+    return _PyMutex_IsLocked(m);
+}