Skip to content

Commit 198f04b

Browse files
committed
refactor: pull out to file
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
1 parent 3af2d84 commit 198f04b

File tree

6 files changed

+56
-41
lines changed

6 files changed

+56
-41
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ set(PYBIND11_HEADERS
205205
include/pybind11/conduit/pybind11_conduit_v1.h
206206
include/pybind11/conduit/pybind11_platform_abi_id.h
207207
include/pybind11/conduit/wrap_include_python_h.h
208+
include/pybind11/critical_section.h
208209
include/pybind11/options.h
209210
include/pybind11/eigen.h
210211
include/pybind11/eigen/common.h

docs/advanced/misc.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ using a Python critical section. This will do nothing if not in free-threaded
301301
Python. You can have it lock one or two Python objects. You cannot nest it.
302302

303303
.. code-block:: cpp
304-
:emphasize-lines: 1,5,10
304+
:emphasize-lines: 4,8
305+
#include <pybind11/critical_section.h>
306+
// ...
305307
306308
PYBIND11_MODULE(example, m, py::multiple_interpreters::per_interpreter_gil(), py::mod_gil_not_used()) {
307309
m.def("calc_next", []() {

include/pybind11/critical_section.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2016-2025 The Pybind Development Team.
2+
// All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#pragma once
6+
7+
#include "pytypes.h"
8+
9+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
10+
11+
/// This does not do anything if there's a GIL. On free-threaded Python,
12+
/// it locks an object. This uses the CPython API, which has limits
13+
class scoped_critical_section {
14+
public:
15+
#ifdef Py_GIL_DISABLED
16+
explicit scoped_critical_section(handle obj) : has2(false) {
17+
PyCriticalSection_Begin(&section, obj.ptr());
18+
}
19+
20+
scoped_critical_section(handle obj1, handle obj2) : has2(true) {
21+
PyCriticalSection2_Begin(&section2, obj1.ptr(), obj2.ptr());
22+
}
23+
24+
~scoped_critical_section() {
25+
if(has2) {
26+
PyCriticalSection2_End(&section2);
27+
} else {
28+
PyCriticalSection_End(&section);
29+
}
30+
}
31+
#else
32+
explicit scoped_critical_section(handle _obj) = default;
33+
scoped_critical_section(handle _obj1, handle _obj2) = default;
34+
~scoped_critical_section() = default;
35+
#endif
36+
37+
scoped_critical_section(const scoped_critical_section &) = delete;
38+
scoped_critical_section &operator=(const scoped_critical_section &) = delete;
39+
40+
private:
41+
#ifdef Py_GIL_DISABLED
42+
bool has2;
43+
union {
44+
PyCriticalSection section;
45+
PyCriticalSection2 section2;
46+
};
47+
#endif
48+
};
49+
50+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

include/pybind11/gil.h

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -199,43 +199,3 @@ class gil_scoped_release {
199199
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
200200

201201
#endif // !PYBIND11_SIMPLE_GIL_MANAGEMENT
202-
203-
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
204-
205-
class scoped_critical_section {
206-
public:
207-
/// This does not do anything if there's a GIL. On free-threaded Python,
208-
/// it locks an object. This uses the CPython API, which has limits
209-
scoped_critical_section(handle obj) : single(true) {
210-
#ifdef Py_GIL_DISABLED
211-
PyCriticalSection_Begin(&section, obj.ptr());
212-
#endif
213-
}
214-
215-
scoped_critical_section(handle obj1, handle obj2) : single(true) {
216-
#ifdef Py_GIL_DISABLED
217-
PyCriticalSection2_Begin(&section2, obj1.ptr(), obj2.ptr());
218-
#endif
219-
}
220-
221-
~scoped_critical_section() {
222-
#ifdef Py_GIL_DISABLED
223-
if(single) {
224-
PyCriticalSection_End(&section);
225-
} else {
226-
PyCriticalSection2_End(&section2);
227-
}
228-
#endif
229-
}
230-
231-
private:
232-
bool single;
233-
#ifdef Py_GIL_DISABLED
234-
union {
235-
PyCriticalSection section;
236-
PyCriticalSection2 section2;
237-
};
238-
#endif
239-
};
240-
241-
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

tests/extra_python_package/test_files.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"include/pybind11/chrono.h",
4545
"include/pybind11/common.h",
4646
"include/pybind11/complex.h",
47+
"include/pybind11/critical_section.h",
4748
"include/pybind11/eigen.h",
4849
"include/pybind11/embed.h",
4950
"include/pybind11/eval.h",

tests/test_embed/test_interpreter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <pybind11/embed.h>
2+
#include <pybind11/critical_section.h>
23

34
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
45
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).

0 commit comments

Comments
 (0)