mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-19 22:39:09 +00:00
* chore: handle null for `py::scoped_critical_section` * test: add tests for `py::scoped_critical_section` * test: use assert instead of REQUIRE * feat: enable faulthandler for pytest * chore: use `__has_include(<barrier>)` * fix: fix segmentation fault in test * fix: test critical_section for no-gil only * test: run new tests only * test: ensure non-empty test selection * fix: fix test critical_section * fix: change Python 3.14.0b1/2 xfail tests to non-strict * test: trigger gc manually * test: mark xfail to `DynamicClass` * Use `namespace test_scoped_critical_section_ns` (standard approach to guard against name clashes). * Simplify changes in pybind11/critical_section.h and add test_nullptr_combinations() * test: disable Python devmode in pytest * test: add comprehensive comments for the tests * test: add a summary comment for tests * refactor: simpler impl Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com> Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
57 lines
1.6 KiB
C++
57 lines
1.6 KiB
C++
// Copyright (c) 2016-2025 The Pybind Development Team.
|
|
// All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#pragma once
|
|
|
|
#include "pytypes.h"
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
|
|
/// This does not do anything if there's a GIL. On free-threaded Python,
|
|
/// it locks an object. This uses the CPython API, which has limits
|
|
class scoped_critical_section {
|
|
public:
|
|
#ifdef Py_GIL_DISABLED
|
|
explicit scoped_critical_section(handle obj1, handle obj2 = handle{}) {
|
|
if (obj1) {
|
|
if (obj2) {
|
|
PyCriticalSection2_Begin(§ion2, obj1.ptr(), obj2.ptr());
|
|
rank = 2;
|
|
} else {
|
|
PyCriticalSection_Begin(§ion, obj1.ptr());
|
|
rank = 1;
|
|
}
|
|
} else if (obj2) {
|
|
PyCriticalSection_Begin(§ion, obj2.ptr());
|
|
rank = 1;
|
|
}
|
|
}
|
|
|
|
~scoped_critical_section() {
|
|
if (rank == 1) {
|
|
PyCriticalSection_End(§ion);
|
|
} else if (rank == 2) {
|
|
PyCriticalSection2_End(§ion2);
|
|
}
|
|
}
|
|
#else
|
|
explicit scoped_critical_section(handle, handle = handle{}) {};
|
|
~scoped_critical_section() = default;
|
|
#endif
|
|
|
|
scoped_critical_section(const scoped_critical_section &) = delete;
|
|
scoped_critical_section &operator=(const scoped_critical_section &) = delete;
|
|
|
|
private:
|
|
#ifdef Py_GIL_DISABLED
|
|
int rank{0};
|
|
union {
|
|
PyCriticalSection section;
|
|
PyCriticalSection2 section2;
|
|
};
|
|
#endif
|
|
};
|
|
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|