Warning, file /include/pybind11/detail/internals.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #pragma once
0011
0012 #include <pybind11/conduit/pybind11_platform_abi_id.h>
0013 #include <pybind11/gil_simple.h>
0014 #include <pybind11/pytypes.h>
0015 #include <pybind11/trampoline_self_life_support.h>
0016
0017 #include "common.h"
0018 #include "struct_smart_holder.h"
0019
0020 #include <atomic>
0021 #include <cstdint>
0022 #include <exception>
0023 #include <limits>
0024 #include <mutex>
0025 #include <thread>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifndef PYBIND11_INTERNALS_VERSION
0042 # define PYBIND11_INTERNALS_VERSION 11
0043 #endif
0044
0045 #if PYBIND11_INTERNALS_VERSION < 11
0046 # error "PYBIND11_INTERNALS_VERSION 11 is the minimum for all platforms for pybind11v3."
0047 #endif
0048
0049 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0050
0051 using ExceptionTranslator = void (*)(std::exception_ptr);
0052
0053
0054
0055
0056
0057 #define PYBIND11_TLS_KEY_REF Py_tss_t &
0058 #if defined(__clang__)
0059 # define PYBIND11_TLS_KEY_INIT(var) \
0060 _Pragma("clang diagnostic push") \
0061 _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \
0062 Py_tss_t var \
0063 = Py_tss_NEEDS_INIT; \
0064 _Pragma("clang diagnostic pop")
0065 #elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
0066 # define PYBIND11_TLS_KEY_INIT(var) \
0067 _Pragma("GCC diagnostic push") \
0068 _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
0069 Py_tss_t var \
0070 = Py_tss_NEEDS_INIT; \
0071 _Pragma("GCC diagnostic pop")
0072 #else
0073 # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
0074 #endif
0075 #define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
0076 #define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
0077 #define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
0078 #define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
0079 #define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
0080
0081
0082
0083 template <typename T>
0084 class thread_specific_storage {
0085 public:
0086 thread_specific_storage() {
0087
0088 if (!PYBIND11_TLS_KEY_CREATE(key_)) {
0089 pybind11_fail(
0090 "thread_specific_storage constructor: could not initialize the TSS key!");
0091 }
0092 }
0093
0094 ~thread_specific_storage() {
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 #ifdef GRAALVM_PYTHON
0106 if (Py_IsInitialized() == 0 || _Py_IsFinalizing() != 0) {
0107 return;
0108 }
0109 #endif
0110 PYBIND11_TLS_FREE(key_);
0111 }
0112
0113 thread_specific_storage(thread_specific_storage const &) = delete;
0114 thread_specific_storage(thread_specific_storage &&) = delete;
0115 thread_specific_storage &operator=(thread_specific_storage const &) = delete;
0116 thread_specific_storage &operator=(thread_specific_storage &&) = delete;
0117
0118 T *get() const { return reinterpret_cast<T *>(PYBIND11_TLS_GET_VALUE(key_)); }
0119
0120 T &operator*() const { return *get(); }
0121 explicit operator T *() const { return get(); }
0122 explicit operator bool() const { return get() != nullptr; }
0123
0124 void set(T *val) { PYBIND11_TLS_REPLACE_VALUE(key_, reinterpret_cast<void *>(val)); }
0125 void reset(T *p = nullptr) { set(p); }
0126 thread_specific_storage &operator=(T *pval) {
0127 set(pval);
0128 return *this;
0129 }
0130
0131 private:
0132 PYBIND11_TLS_KEY_INIT(mutable key_)
0133 };
0134
0135 PYBIND11_NAMESPACE_BEGIN(detail)
0136
0137
0138 #define PYBIND11_DUMMY_MODULE_NAME "pybind11_builtins"
0139
0140
0141 inline PyTypeObject *make_static_property_type();
0142 inline PyTypeObject *make_default_metaclass();
0143 inline PyObject *make_object_base_type(PyTypeObject *metaclass);
0144 inline void translate_exception(std::exception_ptr p);
0145
0146 inline PyThreadState *get_thread_state_unchecked() {
0147 #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
0148 return PyThreadState_GET();
0149 #elif PY_VERSION_HEX < 0x030D0000
0150 return _PyThreadState_UncheckedGet();
0151 #else
0152 return PyThreadState_GetUnchecked();
0153 #endif
0154 }
0155
0156 inline PyInterpreterState *get_interpreter_state_unchecked() {
0157 auto *tstate = get_thread_state_unchecked();
0158 return tstate ? tstate->interp : nullptr;
0159 }
0160
0161 inline object get_python_state_dict() {
0162 object state_dict;
0163 #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
0164 state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
0165 #else
0166 auto *istate = get_interpreter_state_unchecked();
0167 if (istate) {
0168 state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
0169 }
0170 #endif
0171 if (!state_dict) {
0172 raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
0173 throw error_already_set();
0174 }
0175 return state_dict;
0176 }
0177
0178
0179
0180
0181
0182
0183
0184 #if !defined(_LIBCPP_VERSION)
0185 inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
0186 using type_hash = std::hash<std::type_index>;
0187 using type_equal_to = std::equal_to<std::type_index>;
0188 #else
0189 inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
0190 return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
0191 }
0192
0193 struct type_hash {
0194 size_t operator()(const std::type_index &t) const {
0195 size_t hash = 5381;
0196 const char *ptr = t.name();
0197 while (auto c = static_cast<unsigned char>(*ptr++)) {
0198 hash = (hash * 33) ^ c;
0199 }
0200 return hash;
0201 }
0202 };
0203
0204 struct type_equal_to {
0205 bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
0206 return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
0207 }
0208 };
0209 #endif
0210
0211
0212
0213
0214 template <typename value_type>
0215 using fast_type_map = std::unordered_map<const std::type_info *, value_type>;
0216
0217 template <typename value_type>
0218 using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
0219
0220 struct override_hash {
0221 size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
0222 size_t value = std::hash<const void *>()(v.first);
0223 value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
0224 return value;
0225 }
0226 };
0227
0228 using instance_map = std::unordered_multimap<const void *, instance *>;
0229
0230 #ifdef Py_GIL_DISABLED
0231
0232 class pymutex {
0233 friend class pycritical_section;
0234 PyMutex mutex;
0235
0236 public:
0237 pymutex() : mutex({}) {}
0238 void lock() { PyMutex_Lock(&mutex); }
0239 void unlock() { PyMutex_Unlock(&mutex); }
0240 };
0241
0242 class pycritical_section {
0243 pymutex &mutex;
0244 # if PY_VERSION_HEX >= 0x030E00C1
0245 PyCriticalSection cs;
0246 # endif
0247
0248 public:
0249 explicit pycritical_section(pymutex &m) : mutex(m) {
0250
0251 # if PY_VERSION_HEX >= 0x030E00C1
0252 PyCriticalSection_BeginMutex(&cs, &mutex.mutex);
0253 # else
0254
0255 mutex.lock();
0256 # endif
0257 }
0258 ~pycritical_section() {
0259 # if PY_VERSION_HEX >= 0x030E00C1
0260 PyCriticalSection_End(&cs);
0261 # else
0262 mutex.unlock();
0263 # endif
0264 }
0265
0266
0267 pycritical_section(const pycritical_section &) = delete;
0268 pycritical_section &operator=(const pycritical_section &) = delete;
0269 pycritical_section(pycritical_section &&) = delete;
0270 pycritical_section &operator=(pycritical_section &&) = delete;
0271 };
0272
0273
0274 struct instance_map_shard {
0275 instance_map registered_instances;
0276 pymutex mutex;
0277
0278 char padding[64 - (sizeof(instance_map) + sizeof(pymutex)) % 64];
0279 };
0280
0281 static_assert(sizeof(instance_map_shard) % 64 == 0,
0282 "instance_map_shard size is not a multiple of 64 bytes");
0283
0284 inline uint64_t round_up_to_next_pow2(uint64_t x) {
0285
0286
0287 x--;
0288 x |= (x >> 1);
0289 x |= (x >> 2);
0290 x |= (x >> 4);
0291 x |= (x >> 8);
0292 x |= (x >> 16);
0293 x |= (x >> 32);
0294 x++;
0295 return x;
0296 }
0297 #endif
0298
0299 class loader_life_support;
0300
0301
0302
0303
0304 struct internals {
0305 #ifdef Py_GIL_DISABLED
0306 pymutex mutex;
0307 pymutex exception_translator_mutex;
0308 #endif
0309 #if PYBIND11_INTERNALS_VERSION >= 12
0310
0311
0312
0313
0314
0315 fast_type_map<type_info *> registered_types_cpp_fast;
0316 #endif
0317
0318
0319 type_map<type_info *> registered_types_cpp;
0320
0321 std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
0322 #ifdef Py_GIL_DISABLED
0323 std::unique_ptr<instance_map_shard[]> instance_shards;
0324 size_t instance_shards_mask = 0;
0325 #else
0326 instance_map registered_instances;
0327 #endif
0328 std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
0329 inactive_override_cache;
0330 type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
0331 std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
0332 std::forward_list<ExceptionTranslator> registered_exception_translators;
0333 std::unordered_map<std::string, void *> shared_data;
0334
0335 std::forward_list<std::string> static_strings;
0336
0337 PyTypeObject *static_property_type = nullptr;
0338 PyTypeObject *default_metaclass = nullptr;
0339 PyObject *instance_base = nullptr;
0340
0341 thread_specific_storage<PyThreadState> tstate;
0342 #if PYBIND11_INTERNALS_VERSION <= 11
0343 thread_specific_storage<loader_life_support> loader_life_support_tls;
0344 #endif
0345
0346 PyInterpreterState *istate = nullptr;
0347
0348 type_map<PyObject *> native_enum_type_map;
0349
0350 internals()
0351 : static_property_type(make_static_property_type()),
0352 default_metaclass(make_default_metaclass()), istate(get_interpreter_state_unchecked()) {
0353 tstate.set(nullptr);
0354 registered_exception_translators.push_front(&translate_exception);
0355 #ifdef Py_GIL_DISABLED
0356
0357
0358 auto num_shards = static_cast<std::uint16_t>(
0359 std::min<std::size_t>(round_up_to_next_pow2(2 * std::thread::hardware_concurrency()),
0360 std::numeric_limits<std::uint16_t>::max()));
0361 if (num_shards == 0) {
0362 num_shards = 1;
0363 }
0364 instance_shards.reset(new instance_map_shard[num_shards]);
0365 instance_shards_mask = num_shards - 1;
0366 #endif
0367 }
0368 internals(const internals &other) = delete;
0369 internals(internals &&other) = delete;
0370 internals &operator=(const internals &other) = delete;
0371 internals &operator=(internals &&other) = delete;
0372 ~internals() = default;
0373 };
0374
0375
0376
0377
0378
0379
0380
0381 struct local_internals {
0382
0383
0384
0385 fast_type_map<type_info *> registered_types_cpp;
0386
0387 std::forward_list<ExceptionTranslator> registered_exception_translators;
0388 PyTypeObject *function_record_py_type = nullptr;
0389 };
0390
0391 enum class holder_enum_t : uint8_t {
0392 undefined,
0393 std_unique_ptr,
0394 std_shared_ptr,
0395 smart_holder,
0396 custom_holder,
0397 };
0398
0399
0400
0401 struct type_info {
0402 PyTypeObject *type;
0403 const std::type_info *cpptype;
0404 size_t type_size, type_align, holder_size_in_ptrs;
0405 void *(*operator_new)(size_t);
0406 void (*init_instance)(instance *, const void *);
0407 void (*dealloc)(value_and_holder &v_h);
0408
0409
0410
0411 memory::get_guarded_delete_fn get_memory_guarded_delete = memory::get_guarded_delete;
0412 get_trampoline_self_life_support_fn get_trampoline_self_life_support = nullptr;
0413
0414 std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
0415 std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
0416 std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
0417 buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
0418 void *get_buffer_data = nullptr;
0419 void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
0420 holder_enum_t holder_enum_v = holder_enum_t::undefined;
0421
0422 #if PYBIND11_INTERNALS_VERSION >= 12
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 std::forward_list<const std::type_info *> alias_chain;
0433 #endif
0434
0435
0436
0437
0438
0439 bool simple_type : 1;
0440
0441 bool simple_ancestors : 1;
0442
0443 bool module_local : 1;
0444 };
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 struct native_enum_record {
0456 const std::type_info *cpptype;
0457 uint32_t size_bytes;
0458 bool is_signed;
0459 const uint8_t version = 1;
0460
0461 static const char *attribute_name() { return "__pybind11_native_enum__"; }
0462 };
0463
0464 #define PYBIND11_INTERNALS_ID \
0465 "__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
0466 PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
0467
0468 #define PYBIND11_MODULE_LOCAL_ID \
0469 "__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
0470 PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
0471
0472
0473
0474
0475 inline std::atomic_bool &has_seen_non_main_interpreter() {
0476 static std::atomic_bool multi(false);
0477 return multi;
0478 }
0479
0480 template <class T,
0481 enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
0482 bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
0483 std::exception_ptr nested = exc.nested_ptr();
0484 if (nested != nullptr && nested != p) {
0485 translate_exception(nested);
0486 return true;
0487 }
0488 return false;
0489 }
0490
0491 template <class T,
0492 enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
0493 bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
0494 if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
0495 return handle_nested_exception(*nep, p);
0496 }
0497 return false;
0498 }
0499
0500 inline bool raise_err(PyObject *exc_type, const char *msg) {
0501 if (PyErr_Occurred()) {
0502 raise_from(exc_type, msg);
0503 return true;
0504 }
0505 set_error(exc_type, msg);
0506 return false;
0507 }
0508
0509 inline void translate_exception(std::exception_ptr p) {
0510 if (!p) {
0511 return;
0512 }
0513 try {
0514 std::rethrow_exception(p);
0515 } catch (error_already_set &e) {
0516 handle_nested_exception(e, p);
0517 e.restore();
0518 return;
0519 } catch (const builtin_exception &e) {
0520
0521 if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
0522 handle_nested_exception(*nep, p);
0523 }
0524 e.set_error();
0525 return;
0526 } catch (const std::bad_alloc &e) {
0527 handle_nested_exception(e, p);
0528 raise_err(PyExc_MemoryError, e.what());
0529 return;
0530 } catch (const std::domain_error &e) {
0531 handle_nested_exception(e, p);
0532 raise_err(PyExc_ValueError, e.what());
0533 return;
0534 } catch (const std::invalid_argument &e) {
0535 handle_nested_exception(e, p);
0536 raise_err(PyExc_ValueError, e.what());
0537 return;
0538 } catch (const std::length_error &e) {
0539 handle_nested_exception(e, p);
0540 raise_err(PyExc_ValueError, e.what());
0541 return;
0542 } catch (const std::out_of_range &e) {
0543 handle_nested_exception(e, p);
0544 raise_err(PyExc_IndexError, e.what());
0545 return;
0546 } catch (const std::range_error &e) {
0547 handle_nested_exception(e, p);
0548 raise_err(PyExc_ValueError, e.what());
0549 return;
0550 } catch (const std::overflow_error &e) {
0551 handle_nested_exception(e, p);
0552 raise_err(PyExc_OverflowError, e.what());
0553 return;
0554 } catch (const std::exception &e) {
0555 handle_nested_exception(e, p);
0556 raise_err(PyExc_RuntimeError, e.what());
0557 return;
0558 } catch (const std::nested_exception &e) {
0559 handle_nested_exception(e, p);
0560 raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
0561 return;
0562 } catch (...) {
0563 raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
0564 return;
0565 }
0566 }
0567
0568 #if !defined(__GLIBCXX__)
0569 inline void translate_local_exception(std::exception_ptr p) {
0570 try {
0571 if (p) {
0572 std::rethrow_exception(p);
0573 }
0574 } catch (error_already_set &e) {
0575 e.restore();
0576 return;
0577 } catch (const builtin_exception &e) {
0578 e.set_error();
0579 return;
0580 }
0581 }
0582 #endif
0583
0584
0585
0586 #define PYBIND11_DTOR_USE_DELETE (reinterpret_cast<void (*)(PyObject *)>(1))
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608 template <typename Payload>
0609 std::pair<Payload *, bool> atomic_get_or_create_in_state_dict(const char *key,
0610 void (*dtor)(PyObject *)
0611 = PYBIND11_DTOR_USE_DELETE) {
0612 error_scope err_scope;
0613
0614 auto state_dict = reinterpret_borrow<dict>(get_python_state_dict());
0615 PyObject *capsule_obj = nullptr;
0616 bool created = false;
0617
0618
0619 capsule_obj = dict_getitemstring(state_dict.ptr(), key);
0620 if (capsule_obj == nullptr) {
0621 if (PyErr_Occurred()) {
0622 throw error_already_set();
0623 }
0624
0625
0626
0627 auto storage_ptr = std::unique_ptr<Payload>(new Payload{});
0628 auto new_capsule
0629 = capsule(storage_ptr.get(),
0630
0631
0632
0633
0634 [](void *v) { delete static_cast<Payload *>(v); });
0635
0636
0637 (void) storage_ptr.release();
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647 capsule_obj = dict_setdefaultstring(state_dict.ptr(), key, new_capsule.ptr());
0648 if (capsule_obj == nullptr) {
0649 throw error_already_set();
0650 }
0651 created = (capsule_obj == new_capsule.ptr());
0652
0653
0654
0655
0656
0657 if (created && dtor != PYBIND11_DTOR_USE_DELETE) {
0658 if (PyCapsule_SetDestructor(capsule_obj, dtor) < 0) {
0659 throw error_already_set();
0660 }
0661 }
0662 }
0663
0664
0665 void *raw_ptr = PyCapsule_GetPointer(capsule_obj, nullptr);
0666 if (!raw_ptr) {
0667 raise_from(PyExc_SystemError,
0668 "pybind11::detail::atomic_get_or_create_in_state_dict() FAILED");
0669 throw error_already_set();
0670 }
0671 return std::pair<Payload *, bool>(static_cast<Payload *>(raw_ptr), created);
0672 }
0673
0674 #undef PYBIND11_DTOR_USE_DELETE
0675
0676 template <typename InternalsType>
0677 class internals_pp_manager {
0678 public:
0679 using on_fetch_function = void(InternalsType *);
0680
0681 static internals_pp_manager &get_instance(char const *id, on_fetch_function *on_fetch) {
0682 static internals_pp_manager instance(id, on_fetch);
0683 return instance;
0684 }
0685
0686
0687
0688 std::unique_ptr<InternalsType> *get_pp() {
0689 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
0690 if (has_seen_non_main_interpreter()) {
0691
0692
0693
0694 auto *tstate = get_thread_state_unchecked();
0695 if (!tstate || tstate->interp != last_istate_tls()) {
0696 gil_scoped_acquire_simple gil;
0697 if (!tstate) {
0698 tstate = get_thread_state_unchecked();
0699 }
0700 last_istate_tls() = tstate->interp;
0701 internals_p_tls() = get_or_create_pp_in_state_dict();
0702 }
0703 return internals_p_tls();
0704 }
0705 #endif
0706 if (!internals_singleton_pp_) {
0707 gil_scoped_acquire_simple gil;
0708 internals_singleton_pp_ = get_or_create_pp_in_state_dict();
0709 }
0710 return internals_singleton_pp_;
0711 }
0712
0713
0714 void unref() {
0715 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
0716 if (has_seen_non_main_interpreter()) {
0717 last_istate_tls() = nullptr;
0718 internals_p_tls() = nullptr;
0719 return;
0720 }
0721 #endif
0722 internals_singleton_pp_ = nullptr;
0723 }
0724
0725 void destroy() {
0726 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
0727 if (has_seen_non_main_interpreter()) {
0728 auto *tstate = get_thread_state_unchecked();
0729
0730 if (!tstate || tstate->interp == last_istate_tls()) {
0731 auto tpp = internals_p_tls();
0732 {
0733 std::lock_guard<std::mutex> lock(pp_set_mutex_);
0734 pps_have_created_content_.erase(tpp);
0735 }
0736 delete tpp;
0737 }
0738 unref();
0739 return;
0740 }
0741 #endif
0742 {
0743 std::lock_guard<std::mutex> lock(pp_set_mutex_);
0744 pps_have_created_content_.erase(internals_singleton_pp_);
0745 }
0746 delete internals_singleton_pp_;
0747 unref();
0748 }
0749
0750 void create_pp_content_once(std::unique_ptr<InternalsType> *const pp) {
0751
0752
0753
0754 auto tmp = std::unique_ptr<InternalsType>(new InternalsType());
0755
0756 {
0757
0758
0759 std::lock_guard<std::mutex> lock(pp_set_mutex_);
0760
0761 if (*pp) {
0762
0763 return;
0764 }
0765
0766
0767
0768
0769
0770
0771
0772
0773 if (pps_have_created_content_.find(pp) != pps_have_created_content_.end()) {
0774 pybind11_fail(
0775 "pybind11::detail::internals_pp_manager::create_pp_content_once() "
0776 "FAILED: reentrant call detected while fetching pybind11 internals!");
0777 }
0778
0779
0780 pps_have_created_content_.insert(pp);
0781
0782 pp->swap(tmp);
0783 }
0784 }
0785
0786 private:
0787 internals_pp_manager(char const *id, on_fetch_function *on_fetch)
0788 : holder_id_(id), on_fetch_(on_fetch) {}
0789
0790 std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict() {
0791
0792
0793
0794
0795
0796
0797
0798
0799 auto result = atomic_get_or_create_in_state_dict<std::unique_ptr<InternalsType>>(
0800 holder_id_, nullptr );
0801 auto *pp = result.first;
0802 bool created = result.second;
0803
0804 if (!created && on_fetch_ && pp) {
0805 on_fetch_(pp->get());
0806 }
0807 return pp;
0808 }
0809
0810 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
0811 static PyInterpreterState *&last_istate_tls() {
0812 static thread_local PyInterpreterState *last_istate = nullptr;
0813 return last_istate;
0814 }
0815
0816 static std::unique_ptr<InternalsType> *&internals_p_tls() {
0817 static thread_local std::unique_ptr<InternalsType> *internals_p = nullptr;
0818 return internals_p;
0819 }
0820 #endif
0821
0822 char const *holder_id_ = nullptr;
0823 on_fetch_function *on_fetch_ = nullptr;
0824
0825
0826 std::unique_ptr<InternalsType> *internals_singleton_pp_ = nullptr;
0827
0828
0829
0830 std::unordered_set<std::unique_ptr<InternalsType> *> pps_have_created_content_;
0831 std::mutex pp_set_mutex_;
0832 };
0833
0834
0835
0836
0837
0838
0839
0840
0841 #if !defined(__GLIBCXX__)
0842 inline void check_internals_local_exception_translator(internals *internals_ptr) {
0843 if (internals_ptr) {
0844 for (auto et : internals_ptr->registered_exception_translators) {
0845 if (et == &translate_local_exception) {
0846 return;
0847 }
0848 }
0849 internals_ptr->registered_exception_translators.push_front(&translate_local_exception);
0850 }
0851 }
0852 #endif
0853
0854 inline internals_pp_manager<internals> &get_internals_pp_manager() {
0855 #if defined(__GLIBCXX__)
0856 # define ON_FETCH_FN nullptr
0857 #else
0858 # define ON_FETCH_FN &check_internals_local_exception_translator
0859 #endif
0860 return internals_pp_manager<internals>::get_instance(PYBIND11_INTERNALS_ID, ON_FETCH_FN);
0861 #undef ON_FETCH_FN
0862 }
0863
0864
0865 PYBIND11_NOINLINE internals &get_internals() {
0866 auto &ppmgr = get_internals_pp_manager();
0867 auto &internals_ptr = *ppmgr.get_pp();
0868 if (!internals_ptr) {
0869
0870 gil_scoped_acquire_simple gil;
0871 error_scope err_scope;
0872
0873 ppmgr.create_pp_content_once(&internals_ptr);
0874
0875 if (!internals_ptr->instance_base) {
0876
0877
0878 internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
0879 }
0880 }
0881 return *internals_ptr;
0882 }
0883
0884
0885
0886 inline PyObject *get_internals_capsule() {
0887 auto state_dict = reinterpret_borrow<dict>(get_python_state_dict());
0888 return dict_getitemstring(state_dict.ptr(), PYBIND11_INTERNALS_ID);
0889 }
0890
0891
0892
0893
0894
0895 inline const std::string &get_local_internals_key() {
0896 static const std::string key
0897 = PYBIND11_MODULE_LOCAL_ID + std::to_string(reinterpret_cast<uintptr_t>(&key));
0898 return key;
0899 }
0900
0901
0902
0903 inline PyObject *get_local_internals_capsule() {
0904 const auto &key = get_local_internals_key();
0905 auto state_dict = reinterpret_borrow<dict>(get_python_state_dict());
0906 return dict_getitemstring(state_dict.ptr(), key.c_str());
0907 }
0908
0909 inline void ensure_internals() {
0910 pybind11::detail::get_internals_pp_manager().unref();
0911 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
0912 if (PyInterpreterState_Get() != PyInterpreterState_Main()) {
0913 has_seen_non_main_interpreter() = true;
0914 }
0915 #endif
0916 pybind11::detail::get_internals();
0917 }
0918
0919 inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
0920
0921
0922 return internals_pp_manager<local_internals>::get_instance(get_local_internals_key().c_str(),
0923 nullptr);
0924 }
0925
0926
0927 inline local_internals &get_local_internals() {
0928 auto &ppmgr = get_local_internals_pp_manager();
0929 auto &internals_ptr = *ppmgr.get_pp();
0930 if (!internals_ptr) {
0931 gil_scoped_acquire_simple gil;
0932 error_scope err_scope;
0933
0934 ppmgr.create_pp_content_once(&internals_ptr);
0935 }
0936 return *internals_ptr;
0937 }
0938
0939 #ifdef Py_GIL_DISABLED
0940 # define PYBIND11_LOCK_INTERNALS(internals) pycritical_section lock((internals).mutex)
0941 #else
0942 # define PYBIND11_LOCK_INTERNALS(internals)
0943 #endif
0944
0945 template <typename F>
0946 inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
0947 auto &internals = get_internals();
0948 PYBIND11_LOCK_INTERNALS(internals);
0949 return cb(internals);
0950 }
0951
0952 template <typename F>
0953 inline void with_internals_if_internals(const F &cb) {
0954 auto &ppmgr = get_internals_pp_manager();
0955 auto &internals_ptr = *ppmgr.get_pp();
0956 if (internals_ptr) {
0957 auto &internals = *internals_ptr;
0958 PYBIND11_LOCK_INTERNALS(internals);
0959 cb(internals);
0960 }
0961 }
0962
0963 template <typename F>
0964 inline auto with_exception_translators(const F &cb)
0965 -> decltype(cb(get_internals().registered_exception_translators,
0966 get_local_internals().registered_exception_translators)) {
0967 auto &internals = get_internals();
0968 #ifdef Py_GIL_DISABLED
0969 pycritical_section lock((internals).exception_translator_mutex);
0970 #endif
0971 auto &local_internals = get_local_internals();
0972 return cb(internals.registered_exception_translators,
0973 local_internals.registered_exception_translators);
0974 }
0975
0976 inline std::uint64_t mix64(std::uint64_t z) {
0977
0978
0979
0980 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
0981 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
0982 return z ^ (z >> 31);
0983 }
0984
0985 template <typename F>
0986 inline auto with_instance_map(const void *ptr, const F &cb)
0987 -> decltype(cb(std::declval<instance_map &>())) {
0988 auto &internals = get_internals();
0989
0990 #ifdef Py_GIL_DISABLED
0991
0992
0993
0994
0995
0996 auto addr = reinterpret_cast<std::uintptr_t>(ptr);
0997 auto hash = mix64(static_cast<std::uint64_t>(addr >> 20));
0998 auto idx = static_cast<size_t>(hash & internals.instance_shards_mask);
0999
1000 auto &shard = internals.instance_shards[idx];
1001 std::unique_lock<pymutex> lock(shard.mutex);
1002 return cb(shard.registered_instances);
1003 #else
1004 (void) ptr;
1005 return cb(internals.registered_instances);
1006 #endif
1007 }
1008
1009
1010
1011 inline size_t num_registered_instances() {
1012 auto &internals = get_internals();
1013 #ifdef Py_GIL_DISABLED
1014 size_t count = 0;
1015 for (size_t i = 0; i <= internals.instance_shards_mask; ++i) {
1016 auto &shard = internals.instance_shards[i];
1017 std::unique_lock<pymutex> lock(shard.mutex);
1018 count += shard.registered_instances.size();
1019 }
1020 return count;
1021 #else
1022 return internals.registered_instances.size();
1023 #endif
1024 }
1025
1026
1027
1028
1029
1030 template <typename... Args>
1031 const char *c_str(Args &&...args) {
1032
1033
1034 auto &internals = get_internals();
1035 PYBIND11_LOCK_INTERNALS(internals);
1036 auto &strings = internals.static_strings;
1037 strings.emplace_front(std::forward<Args>(args)...);
1038 return strings.front().c_str();
1039 }
1040
1041 PYBIND11_NAMESPACE_END(detail)
1042
1043
1044
1045
1046 PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
1047 return detail::with_internals([&](detail::internals &internals) {
1048 auto it = internals.shared_data.find(name);
1049 return it != internals.shared_data.end() ? it->second : nullptr;
1050 });
1051 }
1052
1053
1054 PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
1055 return detail::with_internals([&](detail::internals &internals) {
1056 internals.shared_data[name] = data;
1057 return data;
1058 });
1059 }
1060
1061
1062
1063
1064 template <typename T>
1065 T &get_or_create_shared_data(const std::string &name) {
1066 return *detail::with_internals([&](detail::internals &internals) {
1067 auto it = internals.shared_data.find(name);
1068 T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
1069 if (!ptr) {
1070 ptr = new T();
1071 internals.shared_data[name] = ptr;
1072 }
1073 return ptr;
1074 });
1075 }
1076
1077 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)