| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #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 |
| |
|