diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 0ad21b2..cb1bddc 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -9,6 +9,9 @@ #include "meta_base.hpp" #include "meta_states.hpp" +#include "meta_detail/state_registry.hpp" +#include "meta_detail/type_registry.hpp" + namespace meta_hpp::detail { template < typename Class, typename... Args > @@ -85,6 +88,7 @@ namespace meta_hpp operator array_type() const noexcept; private: detail::array_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -212,6 +216,7 @@ namespace meta_hpp Policy = Policy{}); private: detail::class_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -227,6 +232,7 @@ namespace meta_hpp enum_bind& evalue_(std::string name, Enum value, evalue_opts opts); private: detail::enum_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -239,6 +245,7 @@ namespace meta_hpp operator function_type() const noexcept; private: detail::function_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -251,6 +258,7 @@ namespace meta_hpp operator member_type() const noexcept; private: detail::member_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -263,6 +271,7 @@ namespace meta_hpp operator method_type() const noexcept; private: detail::method_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -275,6 +284,7 @@ namespace meta_hpp operator nullptr_type() const noexcept; private: detail::nullptr_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -287,6 +297,7 @@ namespace meta_hpp operator number_type() const noexcept; private: detail::number_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -299,6 +310,7 @@ namespace meta_hpp operator pointer_type() const noexcept; private: detail::pointer_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -311,6 +323,7 @@ namespace meta_hpp operator reference_type() const noexcept; private: detail::reference_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -323,6 +336,7 @@ namespace meta_hpp operator void_type() const noexcept; private: detail::void_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -386,6 +400,7 @@ namespace meta_hpp Policy = Policy{}); private: detail::scope_state_ptr state_; + detail::state_registry::locker locker_; }; } diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index c17f3e0..077c6ec 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; @@ -29,7 +29,7 @@ namespace meta_hpp::detail } [[nodiscard]] scope resolve_scope(std::string_view name) { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; @@ -38,10 +38,18 @@ namespace meta_hpp::detail auto state = scope_state::make(std::string{name}, metadata_map{}); return scopes_.emplace(std::string{name}, std::move(state)).first->second; } + public: + class locker : noncopyable { + public: + explicit locker() + : lock_{instance().mutex_} {} + private: + std::lock_guard lock_; + }; private: state_registry() = default; private: - mutable std::mutex mutex_; + std::recursive_mutex mutex_; std::map> scopes_; }; } diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index d7a59e1..b20ef51 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { return iter->second; @@ -29,7 +29,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { return iter->second; @@ -199,6 +199,14 @@ namespace meta_hpp::detail static void_type_data_ptr data{std::make_shared(type_list{})}; return ensure_type(data); } + public: + class locker : noncopyable { + public: + explicit locker() + : lock_{instance().mutex_} {} + private: + std::lock_guard lock_; + }; private: type_registry() = default; @@ -206,7 +214,7 @@ namespace meta_hpp::detail TypeData ensure_type(const TypeData& type_data) { static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ - const std::lock_guard lock{mutex_}; + const locker lock; type_by_id_[type_data->id] = any_type{type_data}; #ifndef META_HPP_NO_RTTI type_by_rtti_[typeid(Type)] = any_type{type_data}; @@ -215,7 +223,7 @@ namespace meta_hpp::detail return type_data; } private: - mutable std::mutex mutex_; + std::recursive_mutex mutex_; std::map> type_by_id_; std::map> type_by_rtti_; };