@@ -270,9 +270,9 @@ inline PyThreadState *get_thread_state_unchecked() {
270
270
271
271
// / We use this count to figure out if there are multiple sub-interpreters currently present.
272
272
// / Might be read/written from multiple interpreters in multiple threads at the same time with no
273
- // / syncronization . This must never decrease while any interpreter may be running in any thread!
274
- inline std::atomic<int64_t > &get_interpreter_count () {
275
- static std::atomic<int64_t > counter (0 );
273
+ // / synchronization . This must never decrease while any interpreter may be running in any thread!
274
+ inline std::atomic<int > &get_interpreter_count () {
275
+ static std::atomic<int > counter (0 );
276
276
return counter;
277
277
}
278
278
@@ -444,25 +444,9 @@ inline uint64_t round_up_to_next_pow2(uint64_t x) {
444
444
}
445
445
446
446
template <typename InternalsType>
447
- inline InternalsType **find_or_create_internals_pp (char const *state_dict_key) {
448
- #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
449
- gil_scoped_acquire gil;
450
- #else
451
- // Ensure that the GIL is held since we will need to make Python calls.
452
- // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
453
- struct gil_scoped_acquire_local {
454
- gil_scoped_acquire_local () : state(PyGILState_Ensure()) {}
455
- gil_scoped_acquire_local (const gil_scoped_acquire_local &) = delete ;
456
- gil_scoped_acquire_local &operator =(const gil_scoped_acquire_local &) = delete ;
457
- ~gil_scoped_acquire_local () { PyGILState_Release (state); }
458
- const PyGILState_STATE state;
459
- } gil;
460
- #endif
461
-
462
- error_scope err_scope;
463
-
447
+ inline InternalsType **find_internals_pp (char const *state_dict_key) {
464
448
dict state_dict = get_python_state_dict ();
465
- object internals_obj
449
+ auto internals_obj
466
450
= reinterpret_steal<object>(dict_getitemstringref (state_dict.ptr (), state_dict_key));
467
451
if (internals_obj) {
468
452
void *raw_ptr = PyCapsule_GetPointer (internals_obj.ptr (), /* name=*/ nullptr );
@@ -472,21 +456,38 @@ inline InternalsType **find_or_create_internals_pp(char const *state_dict_key) {
472
456
return reinterpret_cast <InternalsType **>(raw_ptr);
473
457
}
474
458
}
475
-
476
- auto pp = new InternalsType *(nullptr );
477
- state_dict[state_dict_key] = capsule (reinterpret_cast <void *>(pp));
478
- return pp;
459
+ return nullptr ;
479
460
}
480
461
462
+ #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
463
+ using simple_gil_scoped_acquire = gil_scoped_acquire;
464
+ #else
465
+ // Cannot use py::gil_scoped_acquire inside get_internals since that calls get_internals.
466
+ struct simple_gil_scoped_acquire {
467
+ simple_gil_scoped_acquire () : state(PyGILState_Ensure()) {}
468
+ simple_gil_scoped_acquire (const simple_gil_scoped_acquire &) = delete ;
469
+ simple_gil_scoped_acquire &operator =(const simple_gil_scoped_acquire &) = delete ;
470
+ simple_gil_scoped_acquire (simple_gil_scoped_acquire &&) = delete ;
471
+ simple_gil_scoped_acquire &operator =(simple_gil_scoped_acquire &&) = delete ;
472
+ ~simple_gil_scoped_acquire () { PyGILState_Release (state); }
473
+ const PyGILState_STATE state;
474
+ };
475
+ #endif
476
+
481
477
// / Return a reference to the current `internals` data
482
478
PYBIND11_NOINLINE internals &get_internals () {
483
479
auto **&internals_pp = get_internals_pp ();
484
480
if (internals_pp && *internals_pp) {
485
481
return **internals_pp;
486
482
}
487
483
488
- internals_pp = find_or_create_internals_pp<internals>(PYBIND11_INTERNALS_ID);
489
- if (*internals_pp) {
484
+ simple_gil_scoped_acquire gil;
485
+
486
+ error_scope err_scope;
487
+
488
+ internals_pp = find_internals_pp<internals>(PYBIND11_INTERNALS_ID);
489
+
490
+ if (internals_pp && *internals_pp) {
490
491
// We loaded the internals through `state_dict`, which means that our `error_already_set`
491
492
// and `builtin_exception` may be different local classes than the ones set up in the
492
493
// initial exception translator, below, so add another for our local exception classes.
@@ -503,10 +504,16 @@ PYBIND11_NOINLINE internals &get_internals() {
503
504
}
504
505
#endif
505
506
} else {
507
+ if (!internals_pp) {
508
+ internals_pp = new internals *(nullptr );
509
+ dict state = get_python_state_dict ();
510
+ state[PYBIND11_INTERNALS_ID] = capsule (reinterpret_cast <void *>(internals_pp));
511
+ }
512
+
506
513
auto *&internals_ptr = *internals_pp;
507
514
internals_ptr = new internals ();
508
515
509
- PyThreadState *tstate = get_thread_state_unchecked ();
516
+ PyThreadState *tstate = PyThreadState_Get ();
510
517
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
511
518
if (!PYBIND11_TLS_KEY_CREATE (internals_ptr->tstate )) {
512
519
pybind11_fail (" get_internals: could not successfully initialize the tstate TSS key!" );
@@ -572,24 +579,37 @@ inline local_internals **&get_local_internals_pp() {
572
579
return s_internals_pp;
573
580
}
574
581
582
+ inline char const *get_local_internals_id () {
583
+ // we create a unique value at first run which is based on a pointer to a (non-thread_local)
584
+ // static value in this function, then multiple loaded modules using this code will still each
585
+ // have a unique key.
586
+ static const std::string this_module_idstr
587
+ = PYBIND11_MODULE_LOCAL_ID
588
+ + std::to_string (reinterpret_cast <uintptr_t >(&this_module_idstr));
589
+ return this_module_idstr.c_str ();
590
+ }
591
+
575
592
// / Works like `get_internals`, but for things which are locally registered.
576
593
inline local_internals &get_local_internals () {
577
594
auto **&local_internals_pp = get_local_internals_pp ();
578
595
if (local_internals_pp && *local_internals_pp) {
579
596
return **local_internals_pp;
580
597
}
581
598
582
- // we create a unique value at first run which is based on a pointer to a (non-thread_local)
583
- // static value in this function, then multiple loaded modules using this code will still each
584
- // have a unique key.
585
- static const std::string this_module_idstr
586
- = PYBIND11_MODULE_LOCAL_ID
587
- + std::to_string (reinterpret_cast <uintptr_t >(&this_module_idstr));
599
+ simple_gil_scoped_acquire gil;
588
600
589
- local_internals_pp = find_or_create_internals_pp<local_internals>(this_module_idstr.c_str ());
601
+ error_scope err_scope;
602
+
603
+ local_internals_pp = find_internals_pp<local_internals>(get_local_internals_id ());
604
+ if (!local_internals_pp) {
605
+ local_internals_pp = new local_internals *(nullptr );
606
+ dict state = get_python_state_dict ();
607
+ state[get_local_internals_id ()] = capsule (reinterpret_cast <void *>(local_internals_pp));
608
+ }
590
609
if (!*local_internals_pp) {
591
610
*local_internals_pp = new local_internals ();
592
611
}
612
+
593
613
return **local_internals_pp;
594
614
}
595
615
0 commit comments