Skip to content

Commit 3d4af60

Browse files
committed
Use direct mutex locking for Python 3.13t
`_PyCriticalSection_BeginSlow` is a private CPython function not exported on Linux. For Python < 3.14.0rc1, use direct `mutex.lock()`/`mutex.unlock()` instead of critical section APIs.
1 parent c17212a commit 3d4af60

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

include/pybind11/detail/internals.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -239,26 +239,29 @@ class pymutex {
239239
void unlock() { PyMutex_Unlock(&mutex); }
240240
};
241241

242-
# if PY_VERSION_HEX < 0x030E00C1 // 3.14.0rc1
243-
// Forward declaration of internal slow path function for usage in pycritical_section
244-
extern "C" void _PyCriticalSection_BeginSlow(PyCriticalSection *c, PyMutex *m);
245-
# endif
246-
247242
class pycritical_section {
248243
pymutex &mutex;
244+
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
249245
PyCriticalSection cs;
246+
# endif
250247

251248
public:
252249
explicit pycritical_section(pymutex &m) : mutex(m) {
253250
// PyCriticalSection_BeginMutex was added in Python 3.15.0a1 and backported to 3.14.0rc1
254251
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
255252
PyCriticalSection_BeginMutex(&cs, &mutex.mutex);
256253
# else
257-
// Use the slow path of internal API `_PyCriticalSection_BeginMutex` for older versions
258-
_PyCriticalSection_BeginSlow(&cs, &mutex.mutex);
254+
// Fall back to direct mutex locking for older free-threaded Python versions
255+
mutex.lock();
256+
# endif
257+
}
258+
~pycritical_section() {
259+
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
260+
PyCriticalSection_End(&cs);
261+
# else
262+
mutex.unlock();
259263
# endif
260264
}
261-
~pycritical_section() { PyCriticalSection_End(&cs); }
262265

263266
// Non-copyable and non-movable to prevent double-unlock
264267
pycritical_section(const pycritical_section &) = delete;

0 commit comments

Comments
 (0)