diff --git a/include/pybind11/detail/function_record_pyobject.h b/include/pybind11/detail/function_record_pyobject.h index d9c5bad938..694625f89b 100644 --- a/include/pybind11/detail/function_record_pyobject.h +++ b/include/pybind11/detail/function_record_pyobject.h @@ -91,6 +91,7 @@ static PyType_Spec function_record_PyType_Spec function_record_PyType_Slots}; inline PyTypeObject *get_function_record_PyTypeObject() { + PYBIND11_LOCK_INTERNALS(get_internals()); PyTypeObject *&py_type_obj = detail::get_local_internals().function_record_py_type; if (!py_type_obj) { PyObject *py_obj = PyType_FromSpec(&function_record_PyType_Spec); diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index a2512a5527..a07ef1a897 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -205,7 +205,7 @@ PYBIND11_NOINLINE detail::type_info *get_type_info(PyTypeObject *type) { return bases.front(); } -inline detail::type_info *get_local_type_info(const std::type_info &tp) { +inline detail::type_info *get_local_type_info_lock_held(const std::type_info &tp) { const auto &locals = get_local_internals().registered_types_cpp; auto it = locals.find(&tp); if (it != locals.end()) { @@ -214,48 +214,59 @@ inline detail::type_info *get_local_type_info(const std::type_info &tp) { return nullptr; } -inline detail::type_info *get_global_type_info(const std::type_info &tp) { +inline detail::type_info *get_local_type_info(const std::type_info &tp) { + // NB: internals and local_internals share a single mutex + PYBIND11_LOCK_INTERNALS(get_internals()); + return get_local_type_info_lock_held(tp); +} + +inline detail::type_info *get_global_type_info_lock_held(const std::type_info &tp) { // This is a two-level lookup. Hopefully we find the type info in // registered_types_cpp_fast, but if not we try // registered_types_cpp and fill registered_types_cpp_fast for // next time. - return with_internals([&](internals &internals) { - detail::type_info *type_info = nullptr; + detail::type_info *type_info = nullptr; + auto &internals = get_internals(); #if PYBIND11_INTERNALS_VERSION >= 12 - auto &fast_types = internals.registered_types_cpp_fast; + auto &fast_types = internals.registered_types_cpp_fast; #endif - auto &types = internals.registered_types_cpp; + auto &types = internals.registered_types_cpp; #if PYBIND11_INTERNALS_VERSION >= 12 - auto fast_it = fast_types.find(&tp); - if (fast_it != fast_types.end()) { + auto fast_it = fast_types.find(&tp); + if (fast_it != fast_types.end()) { # ifndef NDEBUG - auto types_it = types.find(std::type_index(tp)); - assert(types_it != types.end()); - assert(types_it->second == fast_it->second); + auto types_it = types.find(std::type_index(tp)); + assert(types_it != types.end()); + assert(types_it->second == fast_it->second); # endif - return fast_it->second; - } + return fast_it->second; + } #endif // PYBIND11_INTERNALS_VERSION >= 12 - auto it = types.find(std::type_index(tp)); - if (it != types.end()) { + auto it = types.find(std::type_index(tp)); + if (it != types.end()) { #if PYBIND11_INTERNALS_VERSION >= 12 - fast_types.emplace(&tp, it->second); + fast_types.emplace(&tp, it->second); #endif - type_info = it->second; - } - return type_info; - }); + type_info = it->second; + } + return type_info; +} + +inline detail::type_info *get_global_type_info(const std::type_info &tp) { + PYBIND11_LOCK_INTERNALS(get_internals()); + return get_global_type_info_lock_held(tp); } /// Return the type info for a given C++ type; on lookup failure can either throw or return /// nullptr. PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_info &tp, bool throw_if_missing = false) { - if (auto *ltype = get_local_type_info(tp)) { + PYBIND11_LOCK_INTERNALS(get_internals()); + if (auto *ltype = get_local_type_info_lock_held(tp)) { return ltype; } - if (auto *gtype = get_global_type_info(tp)) { + if (auto *gtype = get_global_type_info_lock_held(tp)) { return gtype; }