Skip to content

Commit cc50aa9

Browse files
committed
[skip ci] Factor out pybind11/gil_simple.h
1 parent f3c1913 commit cc50aa9

File tree

5 files changed

+62
-55
lines changed

5 files changed

+62
-55
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ set(PYBIND11_HEADERS
158158
include/pybind11/eval.h
159159
include/pybind11/gil.h
160160
include/pybind11/gil_safe_call_once.h
161+
include/pybind11/gil_simple.h
161162
include/pybind11/iostream.h
162163
include/pybind11/functional.h
163164
include/pybind11/native_enum.h

include/pybind11/detail/internals.h

+4-19
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,12 @@
99

1010
#pragma once
1111

12-
#include "common.h"
13-
14-
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
15-
# include <pybind11/gil.h>
16-
#endif
17-
1812
#include <pybind11/conduit/pybind11_platform_abi_id.h>
13+
#include <pybind11/gil_simple.h>
1914
#include <pybind11/pytypes.h>
2015

16+
#include "common.h"
17+
2118
#include <exception>
2219
#include <mutex>
2320
#include <thread>
@@ -425,19 +422,7 @@ PYBIND11_NOINLINE internals &get_internals() {
425422
return **internals_pp;
426423
}
427424

428-
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
429-
gil_scoped_acquire gil;
430-
#else
431-
// Ensure that the GIL is held since we will need to make Python calls.
432-
// Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
433-
struct gil_scoped_acquire_local {
434-
gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}
435-
gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;
436-
gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;
437-
~gil_scoped_acquire_local() { PyGILState_Release(state); }
438-
const PyGILState_STATE state;
439-
} gil;
440-
#endif
425+
gil_scoped_acquire_simple gil;
441426
error_scope err_scope;
442427

443428
dict state_dict = get_python_state_dict();

include/pybind11/gil.h

+17-36
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,24 @@
99

1010
#pragma once
1111

12-
#include "detail/common.h"
12+
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
1313

14-
#include <cassert>
14+
# include "detail/common.h"
15+
# include "gil_simple.h"
1516

16-
#if !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
17+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
18+
19+
using gil_scoped_acquire = gil_scoped_acquire_simple;
20+
using gil_scoped_release = gil_scoped_release_simple;
21+
22+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
23+
24+
#else
25+
26+
# include "detail/common.h"
1727
# include "detail/internals.h"
18-
#endif
28+
29+
# include <cassert>
1930

2031
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
2132

@@ -26,8 +37,6 @@ PyThreadState *get_thread_state_unchecked();
2637

2738
PYBIND11_NAMESPACE_END(detail)
2839

29-
#if !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
30-
3140
/* The functions below essentially reproduce the PyGILState_* API using a RAII
3241
* pattern, but there are a few important differences:
3342
*
@@ -182,34 +191,6 @@ class gil_scoped_release {
182191
bool active = true;
183192
};
184193

185-
#else // PYBIND11_SIMPLE_GIL_MANAGEMENT
186-
187-
class gil_scoped_acquire {
188-
PyGILState_STATE state;
189-
190-
public:
191-
gil_scoped_acquire() : state{PyGILState_Ensure()} {}
192-
gil_scoped_acquire(const gil_scoped_acquire &) = delete;
193-
gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
194-
~gil_scoped_acquire() { PyGILState_Release(state); }
195-
void disarm() {}
196-
};
197-
198-
class gil_scoped_release {
199-
PyThreadState *state;
200-
201-
public:
202-
// PRECONDITION: The GIL must be held when this constructor is called.
203-
gil_scoped_release() {
204-
assert(PyGILState_Check());
205-
state = PyEval_SaveThread();
206-
}
207-
gil_scoped_release(const gil_scoped_release &) = delete;
208-
gil_scoped_release &operator=(const gil_scoped_release &) = delete;
209-
~gil_scoped_release() { PyEval_RestoreThread(state); }
210-
void disarm() {}
211-
};
212-
213-
#endif // PYBIND11_SIMPLE_GIL_MANAGEMENT
214-
215194
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
195+
196+
#endif // !PYBIND11_SIMPLE_GIL_MANAGEMENT

include/pybind11/gil_simple.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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 "detail/common.h"
8+
9+
#include <cassert>
10+
11+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
12+
13+
class gil_scoped_acquire_simple {
14+
PyGILState_STATE state;
15+
16+
public:
17+
gil_scoped_acquire_simple() : state{PyGILState_Ensure()} {}
18+
gil_scoped_acquire_simple(const gil_scoped_acquire_simple &) = delete;
19+
gil_scoped_acquire_simple &operator=(const gil_scoped_acquire_simple &) = delete;
20+
~gil_scoped_acquire_simple() { PyGILState_Release(state); }
21+
void disarm() {}
22+
};
23+
24+
class gil_scoped_release_simple {
25+
PyThreadState *state;
26+
27+
public:
28+
// PRECONDITION: The GIL must be held when this constructor is called.
29+
gil_scoped_release_simple() {
30+
assert(PyGILState_Check());
31+
state = PyEval_SaveThread();
32+
}
33+
gil_scoped_release_simple(const gil_scoped_release_simple &) = delete;
34+
gil_scoped_release_simple &operator=(const gil_scoped_release_simple &) = delete;
35+
~gil_scoped_release_simple() { PyEval_RestoreThread(state); }
36+
void disarm() {}
37+
};
38+
39+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

tests/extra_python_package/test_files.py

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"include/pybind11/functional.h",
3838
"include/pybind11/gil.h",
3939
"include/pybind11/gil_safe_call_once.h",
40+
"include/pybind11/gil_simple.h",
4041
"include/pybind11/iostream.h",
4142
"include/pybind11/native_enum.h",
4243
"include/pybind11/numpy.h",

0 commit comments

Comments
 (0)