|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
|
|
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT) |
|
|
|
|
|
# include "detail/common.h" |
|
|
# include "gil_simple.h" |
|
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
|
|
|
|
|
using gil_scoped_acquire = gil_scoped_acquire_simple; |
|
|
using gil_scoped_release = gil_scoped_release_simple; |
|
|
|
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) |
|
|
|
|
|
#else |
|
|
|
|
|
# include "detail/common.h" |
|
|
# include "detail/internals.h" |
|
|
|
|
|
# include <cassert> |
|
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
|
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(detail) |
|
|
|
|
|
PYBIND11_WARNING_PUSH |
|
|
PYBIND11_WARNING_DISABLE_GCC("-Wredundant-decls") |
|
|
|
|
|
|
|
|
PyThreadState *get_thread_state_unchecked(); |
|
|
|
|
|
PYBIND11_WARNING_POP |
|
|
|
|
|
PYBIND11_NAMESPACE_END(detail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class gil_scoped_acquire { |
|
|
public: |
|
|
PYBIND11_NOINLINE gil_scoped_acquire() { |
|
|
auto &internals = detail::get_internals(); |
|
|
tstate = internals.tstate.get(); |
|
|
|
|
|
if (!tstate) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tstate = PyGILState_GetThisThreadState(); |
|
|
} |
|
|
|
|
|
if (!tstate) { |
|
|
tstate = PyThreadState_New(internals.istate); |
|
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES) |
|
|
if (!tstate) { |
|
|
pybind11_fail("scoped_acquire: could not create thread state!"); |
|
|
} |
|
|
# endif |
|
|
tstate->gilstate_counter = 0; |
|
|
internals.tstate = tstate; |
|
|
} else { |
|
|
release = detail::get_thread_state_unchecked() != tstate; |
|
|
} |
|
|
|
|
|
if (release) { |
|
|
PyEval_AcquireThread(tstate); |
|
|
} |
|
|
|
|
|
inc_ref(); |
|
|
} |
|
|
|
|
|
gil_scoped_acquire(const gil_scoped_acquire &) = delete; |
|
|
gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete; |
|
|
|
|
|
void inc_ref() { ++tstate->gilstate_counter; } |
|
|
|
|
|
PYBIND11_NOINLINE void dec_ref() { |
|
|
--tstate->gilstate_counter; |
|
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES) |
|
|
if (detail::get_thread_state_unchecked() != tstate) { |
|
|
pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!"); |
|
|
} |
|
|
if (tstate->gilstate_counter < 0) { |
|
|
pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!"); |
|
|
} |
|
|
# endif |
|
|
if (tstate->gilstate_counter == 0) { |
|
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES) |
|
|
if (!release) { |
|
|
pybind11_fail("scoped_acquire::dec_ref(): internal error!"); |
|
|
} |
|
|
# endif |
|
|
PyThreadState_Clear(tstate); |
|
|
if (active) { |
|
|
PyThreadState_DeleteCurrent(); |
|
|
} |
|
|
detail::get_internals().tstate.reset(); |
|
|
release = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PYBIND11_NOINLINE void disarm() { active = false; } |
|
|
|
|
|
PYBIND11_NOINLINE ~gil_scoped_acquire() { |
|
|
dec_ref(); |
|
|
if (release) { |
|
|
PyEval_SaveThread(); |
|
|
} |
|
|
} |
|
|
|
|
|
private: |
|
|
PyThreadState *tstate = nullptr; |
|
|
bool release = true; |
|
|
bool active = true; |
|
|
}; |
|
|
|
|
|
class gil_scoped_release { |
|
|
public: |
|
|
|
|
|
explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) { |
|
|
assert(PyGILState_Check()); |
|
|
|
|
|
|
|
|
|
|
|
auto &internals = detail::get_internals(); |
|
|
|
|
|
tstate = PyEval_SaveThread(); |
|
|
if (disassoc) { |
|
|
internals.tstate.reset(); |
|
|
} |
|
|
} |
|
|
|
|
|
gil_scoped_release(const gil_scoped_release &) = delete; |
|
|
gil_scoped_release &operator=(const gil_scoped_release &) = delete; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PYBIND11_NOINLINE void disarm() { active = false; } |
|
|
|
|
|
~gil_scoped_release() { |
|
|
if (!tstate) { |
|
|
return; |
|
|
} |
|
|
|
|
|
if (active) { |
|
|
PyEval_RestoreThread(tstate); |
|
|
} |
|
|
if (disassoc) { |
|
|
detail::get_internals().tstate = tstate; |
|
|
} |
|
|
} |
|
|
|
|
|
private: |
|
|
PyThreadState *tstate; |
|
|
bool disassoc; |
|
|
bool active = true; |
|
|
}; |
|
|
|
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) |
|
|
|
|
|
#endif |
|
|
|