mirror of
https://github.com/pybind/pybind11.git
synced 2026-07-17 00:57:36 +00:00
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.
This commit is contained in:
@@ -248,6 +248,12 @@ public:
|
||||
PyCriticalSection_BeginMutex(&cs, &mutex.mutex);
|
||||
}
|
||||
~pycritical_section() { PyCriticalSection_End(&cs); }
|
||||
|
||||
// Non-copyable and non-movable to prevent double-unlock
|
||||
pycritical_section(const pycritical_section &) = delete;
|
||||
pycritical_section &operator=(const pycritical_section &) = delete;
|
||||
pycritical_section(pycritical_section &&) = delete;
|
||||
pycritical_section &operator=(pycritical_section &&) = delete;
|
||||
};
|
||||
|
||||
// Instance map shards are used to reduce mutex contention in free-threaded Python.
|
||||
|
||||
Reference in New Issue
Block a user