Skip to content

Commit 89b2879

Browse files
committed
Simplify pycritical_section with std::unique_lock fallback for Python < 3.14
1 parent f20f126 commit 89b2879

File tree

1 file changed

+8
-15
lines changed

1 file changed

+8
-15
lines changed

include/pybind11/detail/internals.h

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ using instance_map = std::unordered_multimap<const void *, instance *>;
230230
#ifdef Py_GIL_DISABLED
231231
// Wrapper around PyMutex to provide BasicLockable semantics
232232
class pymutex {
233+
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
233234
friend class pycritical_section;
235+
# endif
234236
PyMutex mutex;
235237

236238
public:
@@ -239,36 +241,27 @@ class pymutex {
239241
void unlock() { PyMutex_Unlock(&mutex); }
240242
};
241243

244+
// PyCriticalSection_BeginMutex was added in Python 3.15.0a1 and backported to 3.14.0rc1
245+
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
242246
class pycritical_section {
243247
pymutex &mutex;
244-
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
245248
PyCriticalSection cs;
246-
# endif
247249

248250
public:
249251
explicit pycritical_section(pymutex &m) : mutex(m) {
250-
// PyCriticalSection_BeginMutex was added in Python 3.15.0a1 and backported to 3.14.0rc1
251-
# if PY_VERSION_HEX >= 0x030E00C1 // 3.14.0rc1
252252
PyCriticalSection_BeginMutex(&cs, &mutex.mutex);
253-
# else
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();
263-
# endif
264253
}
254+
~pycritical_section() { PyCriticalSection_End(&cs); }
265255

266256
// Non-copyable and non-movable to prevent double-unlock
267257
pycritical_section(const pycritical_section &) = delete;
268258
pycritical_section &operator=(const pycritical_section &) = delete;
269259
pycritical_section(pycritical_section &&) = delete;
270260
pycritical_section &operator=(pycritical_section &&) = delete;
271261
};
262+
# else
263+
using pycritical_section = std::unique_lock<pymutex>;
264+
# endif
272265

273266
// Instance map shards are used to reduce mutex contention in free-threaded Python.
274267
struct instance_map_shard {

0 commit comments

Comments
 (0)