@@ -260,7 +260,25 @@ struct type_info {
260
260
// / Each module locally stores a pointer to the `internals` data. The data
261
261
// / itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
262
262
inline internals **&get_internals_pp () {
263
+ #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) || PY_VERSION_HEX < 0x030C0000 \
264
+ || !defined (PYBIND11_SUBINTERPRETER_SUPPORT)
263
265
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
264
282
return internals_pp;
265
283
}
266
284
@@ -427,9 +445,6 @@ PYBIND11_NOINLINE internals &get_internals() {
427
445
return **internals_pp;
428
446
}
429
447
430
- #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
431
- gil_scoped_acquire gil;
432
- #else
433
448
// Ensure that the GIL is held since we will need to make Python calls.
434
449
// Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
435
450
struct gil_scoped_acquire_local {
@@ -439,7 +454,7 @@ PYBIND11_NOINLINE internals &get_internals() {
439
454
~gil_scoped_acquire_local () { PyGILState_Release (state); }
440
455
const PyGILState_STATE state;
441
456
} gil;
442
- # endif
457
+
443
458
error_scope err_scope;
444
459
445
460
dict state_dict = get_python_state_dict ();
@@ -455,7 +470,12 @@ PYBIND11_NOINLINE internals &get_internals() {
455
470
// libc++ with CPython doesn't require this (types are explicitly exported)
456
471
// libc++ with PyPy still need it, awaiting further investigation
457
472
#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
+ }
459
479
#endif
460
480
} else {
461
481
if (!internals_pp) {
@@ -515,7 +535,61 @@ inline local_internals &get_local_internals() {
515
535
// static deinitialization fiasco. In order to avoid it we avoid destruction of the
516
536
// local_internals static. One can read more about the problem and current solution here:
517
537
// 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)
518
541
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
+
519
593
return *locals;
520
594
}
521
595
0 commit comments