@@ -596,8 +596,11 @@ template <typename InternalsType>
596596class internals_pp_manager {
597597public:
598598 using on_fetch_function = void (InternalsType *);
599- internals_pp_manager (char const *id, on_fetch_function *on_fetch)
600- : holder_id_(id), on_fetch_(on_fetch) {}
599+
600+ inline static internals_pp_manager &get_instance (char const *id, on_fetch_function *on_fetch) {
601+ static internals_pp_manager instance (id, on_fetch);
602+ return instance;
603+ }
601604
602605 // / Get the current pointer-to-pointer, allocating it if it does not already exist. May
603606 // / acquire the GIL. Will never return nullptr.
@@ -608,15 +611,15 @@ class internals_pp_manager {
608611 // internals_pp so that it can be pulled from the interpreter's state dict. That is
609612 // slow, so we use the current PyThreadState to check if it is necessary.
610613 auto *tstate = get_thread_state_unchecked ();
611- if (!tstate || tstate->interp != last_istate_. get ()) {
614+ if (!tstate || tstate->interp != last_istate_tls ()) {
612615 gil_scoped_acquire_simple gil;
613616 if (!tstate) {
614617 tstate = get_thread_state_unchecked ();
615618 }
616- last_istate_ = tstate->interp ;
617- internals_tls_p_ = get_or_create_pp_in_state_dict ();
619+ last_istate_tls () = tstate->interp ;
620+ internals_p_tls () = get_or_create_pp_in_state_dict ();
618621 }
619- return internals_tls_p_. get ();
622+ return internals_p_tls ();
620623 }
621624#endif
622625 if (!internals_singleton_pp_) {
@@ -630,8 +633,8 @@ class internals_pp_manager {
630633 void unref () {
631634#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
632635 if (get_num_interpreters_seen () > 1 ) {
633- last_istate_. reset () ;
634- internals_tls_p_. reset () ;
636+ last_istate_tls () = nullptr ;
637+ internals_p_tls () = nullptr ;
635638 return ;
636639 }
637640#endif
@@ -643,8 +646,8 @@ class internals_pp_manager {
643646 if (get_num_interpreters_seen () > 1 ) {
644647 auto *tstate = get_thread_state_unchecked ();
645648 // this could be called without an active interpreter, just use what was cached
646- if (!tstate || tstate->interp == last_istate_. get ()) {
647- auto tpp = internals_tls_p_. get ();
649+ if (!tstate || tstate->interp == last_istate_tls ()) {
650+ auto tpp = internals_p_tls ();
648651 if (tpp) {
649652 delete tpp;
650653 }
@@ -658,6 +661,9 @@ class internals_pp_manager {
658661 }
659662
660663private:
664+ internals_pp_manager (char const *id, on_fetch_function *on_fetch)
665+ : holder_id_(id), on_fetch_(on_fetch) {}
666+
661667 std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict () {
662668 error_scope err_scope;
663669 dict state_dict = get_python_state_dict ();
@@ -683,12 +689,20 @@ class internals_pp_manager {
683689 return pp;
684690 }
685691
686- char const *holder_id_ = nullptr ;
687- on_fetch_function *on_fetch_ = nullptr ;
688692#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
689- thread_specific_storage<PyInterpreterState> last_istate_;
690- thread_specific_storage<std::unique_ptr<InternalsType>> internals_tls_p_;
693+ static PyInterpreterState *&last_istate_tls () {
694+ static thread_local PyInterpreterState *last_istate = nullptr ;
695+ return last_istate;
696+ }
697+
698+ static std::unique_ptr<InternalsType> *&internals_p_tls () {
699+ static thread_local std::unique_ptr<InternalsType> *internals_p = nullptr ;
700+ return internals_p;
701+ }
691702#endif
703+
704+ char const *holder_id_ = nullptr ;
705+ on_fetch_function *on_fetch_ = nullptr ;
692706 std::unique_ptr<InternalsType> *internals_singleton_pp_;
693707};
694708
@@ -718,10 +732,8 @@ inline internals_pp_manager<internals> &get_internals_pp_manager() {
718732#else
719733# define ON_FETCH_FN &check_internals_local_exception_translator
720734#endif
721- static internals_pp_manager<internals> internals_pp_manager (PYBIND11_INTERNALS_ID,
722- ON_FETCH_FN);
735+ return internals_pp_manager<internals>::get_instance (PYBIND11_INTERNALS_ID, ON_FETCH_FN);
723736#undef ON_FETCH_FN
724- return internals_pp_manager;
725737}
726738
727739// / Return a reference to the current `internals` data
@@ -749,9 +761,7 @@ inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
749761 static const std::string this_module_idstr
750762 = PYBIND11_MODULE_LOCAL_ID
751763 + std::to_string (reinterpret_cast <uintptr_t >(&this_module_idstr));
752- static internals_pp_manager<local_internals> local_internals_pp_manager (
753- this_module_idstr.c_str (), nullptr );
754- return local_internals_pp_manager;
764+ return internals_pp_manager<local_internals>::get_instance (this_module_idstr.c_str (), nullptr );
755765}
756766
757767// / Works like `get_internals`, but for things which are locally registered.
0 commit comments