File indexing completed on 2026-09-26 09:06:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #pragma once
0011
0012 #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
0013
0014 # include "detail/common.h"
0015 # include "gil_simple.h"
0016
0017 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0018
0019 using gil_scoped_acquire = gil_scoped_acquire_simple;
0020 using gil_scoped_release = gil_scoped_release_simple;
0021
0022 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
0023
0024 #else
0025
0026 # include "detail/common.h"
0027 # include "detail/internals.h"
0028
0029 # include <cassert>
0030
0031 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0032
0033 PYBIND11_NAMESPACE_BEGIN(detail)
0034
0035 PYBIND11_WARNING_PUSH
0036 PYBIND11_WARNING_DISABLE_GCC("-Wredundant-decls")
0037
0038
0039 PyThreadState *get_thread_state_unchecked();
0040
0041 PYBIND11_WARNING_POP
0042
0043 PYBIND11_NAMESPACE_END(detail)
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 class gil_scoped_acquire {
0068 public:
0069 PYBIND11_NOINLINE gil_scoped_acquire() {
0070 auto &internals = detail::get_internals();
0071 tstate = internals.tstate.get();
0072
0073 if (!tstate) {
0074
0075
0076
0077
0078
0079 tstate = PyGILState_GetThisThreadState();
0080 }
0081
0082 if (!tstate) {
0083 tstate = PyThreadState_New(internals.istate);
0084 # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
0085 if (!tstate) {
0086 pybind11_fail("scoped_acquire: could not create thread state!");
0087 }
0088 # endif
0089 tstate->gilstate_counter = 0;
0090 internals.tstate = tstate;
0091 } else {
0092 release = detail::get_thread_state_unchecked() != tstate;
0093 }
0094
0095 if (release) {
0096 PyEval_AcquireThread(tstate);
0097 }
0098
0099 inc_ref();
0100 }
0101
0102 gil_scoped_acquire(const gil_scoped_acquire &) = delete;
0103 gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
0104
0105 void inc_ref() { ++tstate->gilstate_counter; }
0106
0107 PYBIND11_NOINLINE void dec_ref() {
0108 --tstate->gilstate_counter;
0109 # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
0110 if (detail::get_thread_state_unchecked() != tstate) {
0111 pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
0112 }
0113 if (tstate->gilstate_counter < 0) {
0114 pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!");
0115 }
0116 # endif
0117 if (tstate->gilstate_counter == 0) {
0118 # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
0119 if (!release) {
0120 pybind11_fail("scoped_acquire::dec_ref(): internal error!");
0121 }
0122 # endif
0123
0124
0125 ++tstate->gilstate_counter;
0126 PyThreadState_Clear(tstate);
0127 --tstate->gilstate_counter;
0128 if (active) {
0129 PyThreadState_DeleteCurrent();
0130 }
0131 detail::get_internals().tstate.reset();
0132 release = false;
0133 }
0134 }
0135
0136
0137
0138
0139
0140
0141 PYBIND11_NOINLINE void disarm() { active = false; }
0142
0143 PYBIND11_NOINLINE ~gil_scoped_acquire() {
0144 dec_ref();
0145 if (release) {
0146 PyEval_SaveThread();
0147 }
0148 }
0149
0150 private:
0151 PyThreadState *tstate = nullptr;
0152 bool release = true;
0153 bool active = true;
0154 };
0155
0156 class gil_scoped_release {
0157 public:
0158
0159 explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {
0160 assert(PyGILState_Check());
0161
0162
0163
0164 auto &internals = detail::get_internals();
0165
0166 tstate = PyEval_SaveThread();
0167 if (disassoc) {
0168 internals.tstate.reset();
0169 }
0170 }
0171
0172 gil_scoped_release(const gil_scoped_release &) = delete;
0173 gil_scoped_release &operator=(const gil_scoped_release &) = delete;
0174
0175
0176
0177
0178
0179
0180 PYBIND11_NOINLINE void disarm() { active = false; }
0181
0182 ~gil_scoped_release() {
0183 if (!tstate) {
0184 return;
0185 }
0186
0187 if (active) {
0188 PyEval_RestoreThread(tstate);
0189 }
0190 if (disassoc) {
0191 detail::get_internals().tstate = tstate;
0192 }
0193 }
0194
0195 private:
0196 PyThreadState *tstate;
0197 bool disassoc;
0198 bool active = true;
0199 };
0200
0201 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
0202
0203 #endif