@@ -260,7 +260,25 @@ struct type_info {
260260// / Each module locally stores a pointer to the `internals` data. The data
261261// / itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
262262inline internals **&get_internals_pp () {
263+ #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) || PY_VERSION_HEX < 0x030C0000 \
264+ || !defined (PYBIND11_SUBINTERPRETER_SUPPORT)
263265 static internals **internals_pp = nullptr ;
266+ #else
267+ static thread_local internals **internals_pp = nullptr ;
268+ // This is one per interpreter, we cache it but if the thread changed
269+ // then we need to invalidate our cache
270+ // the caller will find the right value and set it if its null
271+ static thread_local PyThreadState *tstate_cached = nullptr ;
272+ # if PY_VERSION_HEX < 0x030D0000
273+ PyThreadState *tstate = _PyThreadState_UncheckedGet ();
274+ # else
275+ PyThreadState *tstate = PyThreadState_GetUnchecked ();
276+ # endif
277+ if (tstate != tstate_cached) {
278+ tstate_cached = tstate;
279+ internals_pp = nullptr ;
280+ }
281+ #endif
264282 return internals_pp;
265283}
266284
@@ -427,9 +445,6 @@ PYBIND11_NOINLINE internals &get_internals() {
427445 return **internals_pp;
428446 }
429447
430- #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
431- gil_scoped_acquire gil;
432- #else
433448 // Ensure that the GIL is held since we will need to make Python calls.
434449 // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
435450 struct gil_scoped_acquire_local {
@@ -439,7 +454,7 @@ PYBIND11_NOINLINE internals &get_internals() {
439454 ~gil_scoped_acquire_local () { PyGILState_Release (state); }
440455 const PyGILState_STATE state;
441456 } gil;
442- # endif
457+
443458 error_scope err_scope;
444459
445460 dict state_dict = get_python_state_dict ();
@@ -455,7 +470,12 @@ PYBIND11_NOINLINE internals &get_internals() {
455470 // libc++ with CPython doesn't require this (types are explicitly exported)
456471 // libc++ with PyPy still need it, awaiting further investigation
457472#if !defined(__GLIBCXX__)
458- (*internals_pp)->registered_exception_translators .push_front (&translate_local_exception);
473+ if ((*internals_pp)->registered_exception_translators .empty ()
474+ || (*internals_pp)->registered_exception_translators .front ()
475+ != &translate_local_exception) {
476+ (*internals_pp)
477+ ->registered_exception_translators .push_front (&translate_local_exception);
478+ }
459479#endif
460480 } else {
461481 if (!internals_pp) {
@@ -515,7 +535,61 @@ inline local_internals &get_local_internals() {
515535 // static deinitialization fiasco. In order to avoid it we avoid destruction of the
516536 // local_internals static. One can read more about the problem and current solution here:
517537 // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
538+
539+ #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) || PY_VERSION_HEX < 0x030C0000 \
540+ || !defined (PYBIND11_SUBINTERPRETER_SUPPORT)
518541 static auto *locals = new local_internals ();
542+ #else
543+ static thread_local local_internals *locals = nullptr ;
544+ // This is one per interpreter, we cache it but if the interpreter changed
545+ // then we need to invalidate our cache and re-fetch from the state dict
546+ static thread_local PyThreadState *tstate_cached = nullptr ;
547+ # if PY_VERSION_HEX < 0x030D0000
548+ PyThreadState *tstate = _PyThreadState_UncheckedGet ();
549+ # else
550+ PyThreadState *tstate = PyThreadState_GetUnchecked ();
551+ # endif
552+ if (!tstate) {
553+ pybind11_fail (
554+ " pybind11::detail::get_local_internals() called without a current python thread" );
555+ }
556+ if (tstate != tstate_cached) {
557+ // we create a unique value at first run which is based on a pointer to
558+ // a (non-thread_local) static value in this function, then multiple
559+ // loaded modules using this code will still each have a unique key.
560+ static const std::string this_module_idstr
561+ = PYBIND11_MODULE_LOCAL_ID
562+ + std::to_string (reinterpret_cast <uintptr_t >(&this_module_idstr));
563+
564+ // Ensure that the GIL is held since we will need to make Python calls.
565+ // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
566+ struct gil_scoped_acquire_local {
567+ gil_scoped_acquire_local () : state(PyGILState_Ensure()) {}
568+ gil_scoped_acquire_local (const gil_scoped_acquire_local &) = delete ;
569+ gil_scoped_acquire_local &operator =(const gil_scoped_acquire_local &) = delete ;
570+ ~gil_scoped_acquire_local () { PyGILState_Release (state); }
571+ const PyGILState_STATE state;
572+ } gil;
573+
574+ error_scope err_scope;
575+ dict state_dict = get_python_state_dict ();
576+ object local_capsule = reinterpret_steal<object>(
577+ dict_getitemstringref (state_dict.ptr (), this_module_idstr.c_str ()));
578+ if (!local_capsule) {
579+ locals = new local_internals ();
580+ state_dict[this_module_idstr.c_str ()] = capsule (reinterpret_cast <void *>(locals));
581+ } else {
582+ void *ptr = PyCapsule_GetPointer (local_capsule.ptr (), nullptr );
583+ if (!ptr) {
584+ raise_from (PyExc_SystemError, " pybind11::detail::get_local_internals() FAILED" );
585+ throw error_already_set ();
586+ }
587+ locals = reinterpret_cast <local_internals *>(ptr);
588+ }
589+ tstate_cached = tstate;
590+ }
591+ #endif
592+
519593 return *locals;
520594}
521595
0 commit comments