@@ -502,8 +502,11 @@ template <typename InternalsType>
502
502
class internals_pp_manager {
503
503
public:
504
504
using on_fetch_function = void (InternalsType *);
505
- internals_pp_manager (char const *id, on_fetch_function *on_fetch)
506
- : holder_id_(id), on_fetch_(on_fetch) {}
505
+
506
+ inline static internals_pp_manager &get_instance (char const *id, on_fetch_function *on_fetch) {
507
+ static internals_pp_manager instance (id, on_fetch);
508
+ return instance;
509
+ }
507
510
508
511
// / Get the current pointer-to-pointer, allocating it if it does not already exist. May
509
512
// / acquire the GIL. Will never return nullptr.
@@ -514,15 +517,15 @@ class internals_pp_manager {
514
517
// internals_pp so that it can be pulled from the interpreter's state dict. That is
515
518
// slow, so we use the current PyThreadState to check if it is necessary.
516
519
auto *tstate = get_thread_state_unchecked ();
517
- if (!tstate || tstate->interp != last_istate_. get ()) {
520
+ if (!tstate || tstate->interp != last_istate_tls ()) {
518
521
gil_scoped_acquire_simple gil;
519
522
if (!tstate) {
520
523
tstate = get_thread_state_unchecked ();
521
524
}
522
- last_istate_ = tstate->interp ;
523
- internals_tls_p_ = get_or_create_pp_in_state_dict ();
525
+ last_istate_tls () = tstate->interp ;
526
+ internals_p_tls () = get_or_create_pp_in_state_dict ();
524
527
}
525
- return internals_tls_p_. get ();
528
+ return internals_p_tls ();
526
529
}
527
530
#endif
528
531
if (!internals_singleton_pp_) {
@@ -536,8 +539,8 @@ class internals_pp_manager {
536
539
void unref () {
537
540
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
538
541
if (get_num_interpreters_seen () > 1 ) {
539
- last_istate_. reset () ;
540
- internals_tls_p_. reset () ;
542
+ last_istate_tls () = nullptr ;
543
+ internals_p_tls () = nullptr ;
541
544
return ;
542
545
}
543
546
#endif
@@ -549,8 +552,8 @@ class internals_pp_manager {
549
552
if (get_num_interpreters_seen () > 1 ) {
550
553
auto *tstate = get_thread_state_unchecked ();
551
554
// this could be called without an active interpreter, just use what was cached
552
- if (!tstate || tstate->interp == last_istate_. get ()) {
553
- auto tpp = internals_tls_p_. get ();
555
+ if (!tstate || tstate->interp == last_istate_tls ()) {
556
+ auto tpp = internals_p_tls ();
554
557
if (tpp) {
555
558
delete tpp;
556
559
}
@@ -564,6 +567,9 @@ class internals_pp_manager {
564
567
}
565
568
566
569
private:
570
+ internals_pp_manager (char const *id, on_fetch_function *on_fetch)
571
+ : holder_id_(id), on_fetch_(on_fetch) {}
572
+
567
573
std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict () {
568
574
error_scope err_scope;
569
575
dict state_dict = get_python_state_dict ();
@@ -589,12 +595,20 @@ class internals_pp_manager {
589
595
return pp;
590
596
}
591
597
592
- char const *holder_id_ = nullptr ;
593
- on_fetch_function *on_fetch_ = nullptr ;
594
598
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
595
- thread_specific_storage<PyInterpreterState> last_istate_;
596
- thread_specific_storage<std::unique_ptr<InternalsType>> internals_tls_p_;
599
+ static PyInterpreterState *&last_istate_tls () {
600
+ static thread_local PyInterpreterState *last_istate = nullptr ;
601
+ return last_istate;
602
+ }
603
+
604
+ static std::unique_ptr<InternalsType> *&internals_p_tls () {
605
+ static thread_local std::unique_ptr<InternalsType> *internals_p = nullptr ;
606
+ return internals_p;
607
+ }
597
608
#endif
609
+
610
+ char const *holder_id_ = nullptr ;
611
+ on_fetch_function *on_fetch_ = nullptr ;
598
612
std::unique_ptr<InternalsType> *internals_singleton_pp_;
599
613
};
600
614
@@ -624,10 +638,8 @@ inline internals_pp_manager<internals> &get_internals_pp_manager() {
624
638
#else
625
639
# define ON_FETCH_FN &check_internals_local_exception_translator
626
640
#endif
627
- static internals_pp_manager<internals> internals_pp_manager (PYBIND11_INTERNALS_ID,
628
- ON_FETCH_FN);
641
+ return internals_pp_manager<internals>::get_instance (PYBIND11_INTERNALS_ID, ON_FETCH_FN);
629
642
#undef ON_FETCH_FN
630
- return internals_pp_manager;
631
643
}
632
644
633
645
// / Return a reference to the current `internals` data
@@ -655,9 +667,7 @@ inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
655
667
static const std::string this_module_idstr
656
668
= PYBIND11_MODULE_LOCAL_ID
657
669
+ std::to_string (reinterpret_cast <uintptr_t >(&this_module_idstr));
658
- static internals_pp_manager<local_internals> local_internals_pp_manager (
659
- this_module_idstr.c_str (), nullptr );
660
- return local_internals_pp_manager;
670
+ return internals_pp_manager<local_internals>::get_instance (this_module_idstr.c_str (), nullptr );
661
671
}
662
672
663
673
// / Works like `get_internals`, but for things which are locally registered.
0 commit comments