Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,7 @@
#define PYBIND11_CONCAT(first, second) first##second
#define PYBIND11_ENSURE_INTERNALS_READY \
{ \
pybind11::detail::get_internals_pp_manager().unref(); \
pybind11::detail::get_internals(); \
pybind11::detail::ensure_internals(); \
}

#if !defined(GRAALVM_PYTHON)
Expand Down Expand Up @@ -471,7 +470,6 @@ PyModuleDef_Init should be treated like any other PyObject (so not shared across
PYBIND11_CHECK_PYTHON_VERSION \
PYBIND11_PRECOMPILED_CONFIG_GUARD \
try { \
pybind11::detail::ensure_internals(); \
static ::pybind11::detail::slots_array mod_def_slots \
= ::pybind11::detail::init_slots( \
&PYBIND11_CONCAT(pybind11_exec_, name), ##__VA_ARGS__); \
Expand All @@ -494,7 +492,7 @@ PyModuleDef_Init should be treated like any other PyObject (so not shared across
static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &); \
int PYBIND11_CONCAT(pybind11_exec_, name)(PyObject * pm) { \
try { \
pybind11::detail::ensure_internals(); \
PYBIND11_ENSURE_INTERNALS_READY \
auto m = pybind11::reinterpret_borrow<::pybind11::module_>(pm); \
if (!pybind11::detail::get_cached_module(m.attr("__spec__").attr("name"))) { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \
Expand Down
7 changes: 6 additions & 1 deletion include/pybind11/detail/internals-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,17 @@ PYBIND11_INLINE PyObject *get_local_internals_capsule() {
}

PYBIND11_INLINE void ensure_internals() {
pybind11::detail::get_internals_pp_manager().unref();
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
if (PyInterpreterState_Get() != PyInterpreterState_Main()) {
has_seen_non_main_interpreter() = true;
}
#endif
/* In an embedded app the main interpreter could be finalized and re-initialized and a pybind11
* extension module would hold a pointer to a deleted internals. The only way to prevent
* access to that is to re-fetch everything from the state dict here. So we first null it out
* of our global copy and then fetch it (creating it if it does not already exist). */
pybind11::detail::get_internals_pp_manager().unref();
pybind11::detail::get_local_internals_pp_manager().unref();
pybind11::detail::get_internals();
}

Expand Down
3 changes: 2 additions & 1 deletion include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,8 @@ PyObject *cached_create_module(PyObject *spec, PyModuleDef *);
/// the sentinel (0) end slot.
using slots_array = std::array<PyModuleDef_Slot, 5>;

/// Initialize an array of slots based on the supplied exec slot and options.
/** Initialize an array of slots based on the supplied exec slot and options. This code may not
* assume the GIL and may not use pybind11 internals because this runs early during module init. */
template <typename... Options>
inline slots_array init_slots(int (*exec_fn)(PyObject *), Options &&...options) noexcept {
/* NOTE: slots_array MUST be large enough to hold all possible options. If you add an option
Expand Down
Loading