diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 067f8f17f5..991a0e756f 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -428,19 +428,12 @@ class idm // Prepare new ID (returns nullptr if out of resources) static map_data* allocate_id(std::vector& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, std::pair invl_range); - // Find ID (additionally check type if types are not equal) + // Get object by internal index if exists (additionally check type if types are not equal) template - static map_data* find_id(u32 id) + static map_data* find_index(u32 index, u32 id) { static_assert(PtrSame, "Invalid ID type combination"); - const u32 index = get_index(id); - - if (index >= id_manager::id_traits::count) - { - return nullptr; - } - auto& vec = g_fxo->get>().vec; if (index >= vec.size()) @@ -464,6 +457,17 @@ class idm return nullptr; } + // Find ID + template + static map_data* find_id(u32 id) + { + static_assert(PtrSame, "Invalid ID type combination"); + + const u32 index = get_index(id); + + return find_index(index, id); + } + // Allocate new ID (or use fixed ID) and assign the object from the provider() template static map_data* create_id(F&& provider, u32 id = id_manager::id_traits::invalid) @@ -591,12 +595,21 @@ public: // Check the ID, access object under shared lock template > - static inline auto check(u32 id, F&& func) + static inline std::conditional_t, Get*, return_pair> check(u32 id, F&& func) { + const u32 index = get_index(id); + + if (index >= id_manager::id_traits::count) + { + return {}; + } + reader_lock lock(id_manager::g_mutex); - if (const auto ptr = check_unlocked(id)) + if (const auto found = find_index(index, id)) { + const auto ptr = static_cast(found->second.get()); + if constexpr (!std::is_void_v) { return return_pair{ptr, func(*ptr)}; @@ -608,14 +621,7 @@ public: } } - if constexpr (!std::is_void_v) - { - return return_pair{nullptr}; - } - else - { - return static_cast(nullptr); - } + return {}; } // Get the object without locking (can be called from other method) @@ -645,9 +651,16 @@ public: template > static inline std::conditional_t, std::shared_ptr, return_pair> get(u32 id, F&& func) { + const u32 index = get_index(id); + + if (index >= id_manager::id_traits::count) + { + return {nullptr}; + } + reader_lock lock(id_manager::g_mutex); - const auto found = find_id(id); + const auto found = find_index(index, id); if (found == nullptr) [[unlikely]] { @@ -773,9 +786,16 @@ public: template > static inline std::conditional_t, std::shared_ptr, return_pair> withdraw(u32 id, F&& func) { + const u32 index = get_index(id); + + if (index >= id_manager::id_traits::count) + { + return {nullptr}; + } + std::unique_lock lock(id_manager::g_mutex); - if (const auto found = find_id(id)) + if (const auto found = find_index(index, id)) { const auto _ptr = static_cast(found->second.get());