From 52fe86b56c7eb5cadf059a54646215eab8547d06 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 2 Mar 2021 19:22:39 +0300 Subject: [PATCH] fixed_typemap.hpp: make it a bit fool-proof Require objects to be non-copyable (move is still allowed). --- Utilities/bin_patch.h | 4 ++ rpcs3/Emu/Cell/Modules/StaticHLE.h | 3 ++ rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp | 5 ++ rpcs3/Emu/Cell/Modules/cellFs.cpp | 2 + rpcs3/Emu/Cell/Modules/cellMusic.cpp | 6 ++- rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp | 12 +++-- rpcs3/Emu/Cell/Modules/cellRec.cpp | 6 ++- rpcs3/Emu/Cell/Modules/cellRudp.cpp | 4 +- rpcs3/Emu/Cell/Modules/cellScreenshot.cpp | 20 ++++---- rpcs3/Emu/Cell/Modules/cellScreenshot.h | 9 ++-- rpcs3/Emu/Cell/Modules/cellSearch.cpp | 56 ++++++++++++---------- rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp | 6 ++- rpcs3/Emu/Cell/PPUAnalyser.h | 10 ++++ rpcs3/Emu/Cell/PPUModule.cpp | 6 +++ rpcs3/Emu/Cell/PPUThread.cpp | 11 ++++- rpcs3/Emu/Cell/SPUThread.cpp | 6 +++ rpcs3/Input/pad_thread.h | 2 + rpcs3/rpcs3qt/gs_frame.cpp | 8 ++-- rpcs3/util/fixed_typemap.hpp | 2 + 19 files changed, 121 insertions(+), 57 deletions(-) diff --git a/Utilities/bin_patch.h b/Utilities/bin_patch.h index bd522de0ce..d8de70e5da 100644 --- a/Utilities/bin_patch.h +++ b/Utilities/bin_patch.h @@ -89,6 +89,10 @@ public: patch_engine(); + patch_engine(const patch_engine&) = delete; + + patch_engine& operator=(const patch_engine&) = delete; + // Returns the directory in which patch_config.yml is located static std::string get_patch_config_path(); diff --git a/rpcs3/Emu/Cell/Modules/StaticHLE.h b/rpcs3/Emu/Cell/Modules/StaticHLE.h index a02a5f83b5..b55bcc6102 100644 --- a/rpcs3/Emu/Cell/Modules/StaticHLE.h +++ b/rpcs3/Emu/Cell/Modules/StaticHLE.h @@ -22,6 +22,9 @@ public: statichle_handler(int); ~statichle_handler(); + statichle_handler(const statichle_handler&) = delete; + statichle_handler& operator=(const statichle_handler&) = delete; + bool load_patterns(); bool check_against_patterns(vm::cptr& data, u32 size, u32 addr); diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index 74bedd07aa..db8f5f9c0e 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -38,7 +38,12 @@ struct avconf_manager std::vector devices; void copy_device_info(u32 num, vm::ptr info); + avconf_manager(); + + avconf_manager(const avconf_manager&) = delete; + + avconf_manager& operator=(const avconf_manager&) = delete; }; avconf_manager::avconf_manager() diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index 4bc12c36c2..42a1bd538e 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -938,6 +938,8 @@ struct fs_aio_thread : ppu_thread struct fs_aio_manager { std::shared_ptr thread; + + shared_mutex mutex; }; s32 cellFsAioInit(vm::cptr mount_point) diff --git a/rpcs3/Emu/Cell/Modules/cellMusic.cpp b/rpcs3/Emu/Cell/Modules/cellMusic.cpp index cb70d68a04..a2e2393e1d 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusic.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusic.cpp @@ -63,8 +63,10 @@ void fmt_class_string::format(std::string& out, u64 arg) struct music_state { - vm::ptr param, vm::ptr userData)> func; - vm::ptr userData; + shared_mutex mutex; + + vm::ptr param, vm::ptr userData)> func{}; + vm::ptr userData{}; }; error_code cellMusicGetSelectionContext(vm::ptr context) diff --git a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp index 4c7b7699f6..dcf9ed58c9 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp @@ -85,14 +85,18 @@ using CellMusicDecode2Callback = void(u32, vm::ptr param, vm::ptr us struct music_decode { - vm::ptr func; - vm::ptr userData; + vm::ptr func{}; + vm::ptr userData{}; + + shared_mutex mutex; }; struct music_decode2 { - vm::ptr func; - vm::ptr userData; + vm::ptr func{}; + vm::ptr userData{}; + + shared_mutex mutex; }; error_code cellMusicDecodeInitialize(s32 mode, u32 container, s32 spuPriority, vm::ptr func, vm::ptr userData) diff --git a/rpcs3/Emu/Cell/Modules/cellRec.cpp b/rpcs3/Emu/Cell/Modules/cellRec.cpp index c074254c2b..f6e99b1f74 100644 --- a/rpcs3/Emu/Cell/Modules/cellRec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRec.cpp @@ -58,8 +58,10 @@ using CellRecCallback = void(s32 recStatus, s32 recError, vm::ptr userdata struct rec_info { - vm::ptr cb; - vm::ptr cbUserData; + vm::ptr cb{}; + vm::ptr cbUserData{}; + + shared_mutex mutex; }; error_code cellRecOpen(vm::cptr pDirName, vm::cptr pFileName, vm::cptr pParam, u32 container, vm::ptr cb, vm::ptr cbUserData) diff --git a/rpcs3/Emu/Cell/Modules/cellRudp.cpp b/rpcs3/Emu/Cell/Modules/cellRudp.cpp index 40727a6d4b..983d41a1b4 100644 --- a/rpcs3/Emu/Cell/Modules/cellRudp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRudp.cpp @@ -65,7 +65,9 @@ struct rudp_info // event handler function vm::ptr handler = vm::null; - vm::ptr handler_arg; + vm::ptr handler_arg{}; + + shared_mutex mutex; }; error_code cellRudpInit(vm::ptr allocator) diff --git a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp index 34b8821d16..6c35d0df6a 100644 --- a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp +++ b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp @@ -26,14 +26,12 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -shared_mutex screenshot_mtx; - -std::string screenshot_manager::get_overlay_path() const +std::string screenshot_info::get_overlay_path() const { return vfs::get(overlay_dir_name + "/" + overlay_file_name); } -std::string screenshot_manager::get_photo_title() const +std::string screenshot_info::get_photo_title() const { std::string photo = photo_title; if (photo.empty()) @@ -41,7 +39,7 @@ std::string screenshot_manager::get_photo_title() const return photo; } -std::string screenshot_manager::get_game_title() const +std::string screenshot_info::get_game_title() const { std::string game = game_title; if (game.empty()) @@ -49,12 +47,12 @@ std::string screenshot_manager::get_game_title() const return game; } -std::string screenshot_manager::get_game_comment() const +std::string screenshot_info::get_game_comment() const { return game_comment; } -std::string screenshot_manager::get_screenshot_path(const std::string& date_path) const +std::string screenshot_info::get_screenshot_path(const std::string& date_path) const { u32 counter = 0; std::string path = vfs::get("/dev_hdd0/photo/" + date_path + "/" + get_photo_title()); @@ -86,7 +84,7 @@ error_code cellScreenShotSetParameter(vm::cptr param) return CELL_SCREENSHOT_ERROR_PARAM; auto& manager = g_fxo->get(); - std::lock_guard lock(screenshot_mtx); + std::lock_guard lock(manager.mutex); if (param->photo_title && param->photo_title[0] != '\0') manager.photo_title = std::string(param->photo_title.get_ptr()); @@ -124,7 +122,7 @@ error_code cellScreenShotSetOverlayImage(vm::cptr srcDir, vm::cptr s } auto& manager = g_fxo->get(); - std::lock_guard lock(screenshot_mtx); + std::lock_guard lock(manager.mutex); manager.overlay_dir_name = std::string(srcDir.get_ptr()); manager.overlay_file_name = std::string(srcFile.get_ptr()); @@ -139,7 +137,7 @@ error_code cellScreenShotEnable() cellScreenshot.warning("cellScreenShotEnable()"); auto& manager = g_fxo->get(); - std::lock_guard lock(screenshot_mtx); + std::lock_guard lock(manager.mutex); manager.is_enabled = true; @@ -151,7 +149,7 @@ error_code cellScreenShotDisable() cellScreenshot.warning("cellScreenShotDisable()"); auto& manager = g_fxo->get(); - std::lock_guard lock(screenshot_mtx); + std::lock_guard lock(manager.mutex); manager.is_enabled = false; diff --git a/rpcs3/Emu/Cell/Modules/cellScreenshot.h b/rpcs3/Emu/Cell/Modules/cellScreenshot.h index 14b030055c..20a8d41cc5 100644 --- a/rpcs3/Emu/Cell/Modules/cellScreenshot.h +++ b/rpcs3/Emu/Cell/Modules/cellScreenshot.h @@ -27,9 +27,7 @@ struct CellScreenShotSetParam vm::bptr reserved; }; -extern shared_mutex screenshot_mtx; - -struct screenshot_manager +struct screenshot_info { bool is_enabled{false}; @@ -48,3 +46,8 @@ struct screenshot_manager std::string get_game_comment() const; std::string get_screenshot_path(const std::string& date_path) const; }; + +struct screenshot_manager : public screenshot_info +{ + shared_mutex mutex; +}; diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index 0e542934eb..197c36931d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -55,7 +55,6 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -namespace { enum class search_state { not_initialized = 0, @@ -94,8 +93,14 @@ struct search_content_t } data; }; -using ContentIdType = std::pair>; -using ContentIdMap = std::unordered_map>; +using content_id_type = std::pair>; + +struct content_id_map +{ + std::unordered_map> map; + + shared_mutex mutex; +}; struct search_object_t { @@ -103,11 +108,10 @@ struct search_object_t static const u32 id_base = 1; static const u32 id_step = 1; static const u32 id_count = 1024; // TODO - static const u32 invalid = 0xFFFFFFFF; - std::vector content_ids; + std::vector content_ids; }; -} + error_code cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr func, vm::ptr userData) { cellSearch.warning("cellSearchInitialize(mode=0x%x, container=0x%x, func=*0x%x, userData=*0x%x)", +mode, container, func, userData); @@ -242,7 +246,7 @@ error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSo const u32 id = *outSearchId = idm::make(); - sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 + sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 { auto curr_search = idm::get(id); vm::var resultParam; @@ -320,8 +324,8 @@ error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSo } const u64 hash = std::hash()(item_path); - auto found = content_map.find(hash); - if (found == content_map.end()) // content isn't yet being tracked + auto found = content_map.map.find(hash); + if (found == content_map.map.end()) // content isn't yet being tracked { //auto ext_offset = item.name.find_last_of('.'); // used later if no "Title" found @@ -391,7 +395,7 @@ error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSo } } - content_map.emplace(hash, curr_find); + content_map.map.emplace(hash, curr_find); curr_search->content_ids.emplace_back(hash, curr_find); // place this file's "ID" into the list of found types cellSearch.notice("cellSearchStartListSearch(): Content ID: %08X Path: \"%s\"", hash, item_path); @@ -467,9 +471,9 @@ error_code cellSearchStartContentSearchInList(vm::cptr list return CELL_SEARCH_ERROR_GENERIC; } - auto& content_map = g_fxo->get(); - auto found = content_map.find(*reinterpret_cast(listId->data)); - if (found == content_map.end()) + auto& content_map = g_fxo->get(); + auto found = content_map.map.find(*reinterpret_cast(listId->data)); + if (found == content_map.map.end()) { // content ID not found, perform a search first return CELL_SEARCH_ERROR_CONTENT_NOT_FOUND; @@ -553,8 +557,8 @@ error_code cellSearchStartContentSearchInList(vm::cptr list const std::string item_path(vpath + "/" + item.name); const u64 hash = std::hash()(item_path); - auto found = content_map.find(hash); - if (found == content_map.end()) // content isn't yet being tracked + auto found = content_map.map.find(hash); + if (found == content_map.map.end()) // content isn't yet being tracked { auto ext_offset = item.name.find_last_of('.'); // used later if no "Title" found @@ -783,7 +787,7 @@ error_code cellSearchStartContentSearchInList(vm::cptr list strcpy_trunc(info.albumTitle, "ALBUM TITLE"); } - content_map.emplace(hash, curr_find); + content_map.map.emplace(hash, curr_find); curr_search->content_ids.emplace_back(hash, curr_find); // place this file's "ID" into the list of found types cellSearch.notice("cellSearchStartContentSearchInList(): Content ID: %08X Path: \"%s\"", hash, item_path); @@ -871,7 +875,7 @@ error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSe const u32 id = *outSearchId = idm::make(); - sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 + sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 { auto curr_search = idm::get(id); vm::var resultParam; @@ -906,8 +910,8 @@ error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSe const std::string item_path(relative_vpath + "/" + item.name); const u64 hash = std::hash()(item_path); - auto found = content_map.find(hash); - if (found == content_map.end()) // content isn't yet being tracked + auto found = content_map.map.find(hash); + if (found == content_map.map.end()) // content isn't yet being tracked { auto ext_offset = item.name.find_last_of('.'); // used later if no "Title" found @@ -985,7 +989,7 @@ error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSe strcpy_trunc(info.albumTitle, "ALBUM TITLE"); } - content_map.emplace(hash, curr_find); + content_map.map.emplace(hash, curr_find); curr_search->content_ids.emplace_back(hash, curr_find); // place this file's "ID" into the list of found types cellSearch.notice("cellSearchStartContentSearch(): Content ID: %08X Path: \"%s\"", hash, item_path); @@ -1228,9 +1232,9 @@ error_code cellSearchGetContentInfoByContentId(vm::cptr con return CELL_SEARCH_ERROR_GENERIC; } - auto& content_map = g_fxo->get(); - auto found = content_map.find(*reinterpret_cast(contentId->data)); - if (found != content_map.end()) + auto& content_map = g_fxo->get(); + auto found = content_map.map.find(*reinterpret_cast(contentId->data)); + if (found != content_map.map.end()) { const auto& content_info = found->second; switch (content_info->type) @@ -1439,9 +1443,9 @@ error_code cellSearchGetContentInfoPath(vm::cptr contentId, } const u64 id = *reinterpret_cast(contentId->data); - auto& content_map = g_fxo->get(); - auto found = content_map.find(id); - if(found != content_map.end()) + auto& content_map = g_fxo->get(); + auto found = content_map.map.find(id); + if(found != content_map.map.end()) { std::memcpy(infoPath.get_ptr(), &found->second->infoPath, sizeof(found->second->infoPath)); } diff --git a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp index c452965933..8a9991b089 100644 --- a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp +++ b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp @@ -8,8 +8,10 @@ LOG_CHANNEL(cellSysutil); struct browser_info { - vm::ptr system_cb; - vm::ptr userData; + vm::ptr system_cb{}; + vm::ptr userData{}; + + shared_mutex mutex; }; error_code cellWebBrowserActivate() diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 458d74b79f..7b6236ac10 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -69,6 +69,16 @@ struct ppu_segment // PPU Module Information struct ppu_module { + ppu_module() = default; + + ppu_module(const ppu_module&) = delete; + + ppu_module(ppu_module&&) = default; + + ppu_module& operator=(const ppu_module&) = delete; + + ppu_module& operator=(ppu_module&&) = default; + uchar sha1[20]{}; std::string name; std::string path; diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 0767475a7b..80f099496a 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -101,6 +101,12 @@ const ppu_static_module* ppu_module_manager::get_module(const std::string& name) // Global linkage information struct ppu_linkage_info { + ppu_linkage_info() = default; + + ppu_linkage_info(const ppu_linkage_info&) = delete; + + ppu_linkage_info& operator=(const ppu_linkage_info&) = delete; + struct module_data { struct info diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 259574e74e..0759c6d18d 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -2597,6 +2597,13 @@ extern void ppu_initialize() } } +struct ppu_toc_manager +{ + std::unordered_map toc_map; + + shared_mutex mutex; +}; + bool ppu_initialize(const ppu_module& info, bool check_only) { if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm) @@ -2607,7 +2614,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) } // Temporarily - s_ppu_toc = &g_fxo->get>(); + s_ppu_toc = &g_fxo->get().toc_map; for (const auto& func : info.funcs) { @@ -2994,7 +3001,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) } // Keep allocating workload - const auto [obj_name, part] = std::as_const(workload)[i]; + const auto& [obj_name, part] = std::as_const(workload)[i]; // Allocate "core" std::lock_guard jlock(g_fxo->get().sem); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index f529280fb7..c35db82a20 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1665,6 +1665,12 @@ void spu_thread::cpu_task() struct raw_spu_cleanup { + raw_spu_cleanup() = default; + + raw_spu_cleanup(const raw_spu_cleanup&) = delete; + + raw_spu_cleanup& operator =(const raw_spu_cleanup&) = delete; + ~raw_spu_cleanup() { std::memset(spu_thread::g_raw_spu_id, 0, sizeof(spu_thread::g_raw_spu_id)); diff --git a/rpcs3/Input/pad_thread.h b/rpcs3/Input/pad_thread.h index f190649cdc..d4a79d7136 100644 --- a/rpcs3/Input/pad_thread.h +++ b/rpcs3/Input/pad_thread.h @@ -17,6 +17,8 @@ class pad_thread { public: pad_thread(void* _curthread, void* _curwindow, std::string_view title_id); // void * instead of QThread * and QWindow * because of include in emucore + pad_thread(const pad_thread&) = delete; + pad_thread& operator=(const pad_thread&) = delete; ~pad_thread(); PadInfo& GetInfo() { return m_info; } diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index b99010d99a..a5e71d75d8 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -481,11 +481,11 @@ void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot } } - screenshot_manager manager; + screenshot_info manager; { - auto& fxo = g_fxo->get(); - std::lock_guard lock(screenshot_mtx); - manager = fxo; + auto& s = g_fxo->get(); + std::lock_guard lock(s.mutex); + manager = s; } struct scoped_png_ptrs diff --git a/rpcs3/util/fixed_typemap.hpp b/rpcs3/util/fixed_typemap.hpp index b77c14c484..fb4f6cc23f 100644 --- a/rpcs3/util/fixed_typemap.hpp +++ b/rpcs3/util/fixed_typemap.hpp @@ -49,6 +49,8 @@ namespace stx template static typeinfo make_typeinfo() { + static_assert(!std::is_copy_assignable_v && !std::is_copy_constructible_v, "Please make sure the object cannot be accidentally copied."); + typeinfo r; r.create = &call_ctor; r.destroy = &call_dtor;