Skip to content

Commit be01d1e

Browse files
committed
Make pycritical_section non-copyable and non-movable
The pycritical_section class is a RAII wrapper that manages a Python critical section lifecycle: - Acquires the critical section in the constructor via PyCriticalSection_BeginMutex - Releases it in the destructor via PyCriticalSection_End - Holds a reference to a pymutex Allowing copy or move operations would be dangerous: 1. Copy: Both the original and copied objects would call PyCriticalSection_End on the same PyCriticalSection object in their destructors, leading to double-unlock and undefined behavior. 2. Move: The moved-from object's destructor would still run and attempt to end the critical section, while the moved-to object would also try to end it, again causing double-unlock. This follows the same pattern used by other RAII lock guards in the codebase, such as gil_scoped_acquire and gil_scoped_release, which also explicitly delete copy/move operations to prevent similar issues. By explicitly deleting these operations, we prevent accidental misuse and ensure the critical section is properly managed by a single RAII object throughout its lifetime.
1 parent 8690dd7 commit be01d1e

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

include/pybind11/detail/internals.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,12 @@ class pycritical_section {
248248
PyCriticalSection_BeginMutex(&cs, &mutex.mutex);
249249
}
250250
~pycritical_section() { PyCriticalSection_End(&cs); }
251+
252+
// Non-copyable and non-movable to prevent double-unlock
253+
pycritical_section(const pycritical_section &) = delete;
254+
pycritical_section &operator=(const pycritical_section &) = delete;
255+
pycritical_section(pycritical_section &&) = delete;
256+
pycritical_section &operator=(pycritical_section &&) = delete;
251257
};
252258

253259
// Instance map shards are used to reduce mutex contention in free-threaded Python.

0 commit comments

Comments
 (0)