Skip to content

Commit 80154dd

Browse files
committed
Merge remote-tracking branch 'origin/master' into interop
2 parents 11c71cd + 326b106 commit 80154dd

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

include/pybind11/detail/internals.h

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,11 @@ template <typename InternalsType>
596596
class internals_pp_manager {
597597
public:
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

660663
private:
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

Comments
 (0)