diff --git a/Utilities/Config.cpp b/Utilities/Config.cpp index 962a36385b..771dbb7e9e 100644 --- a/Utilities/Config.cpp +++ b/Utilities/Config.cpp @@ -326,7 +326,7 @@ void cfg::_bool::from_default() void cfg::string::from_default() { - m_value = def; + m_value = m_value.make(def); } void cfg::set_entry::from_default() diff --git a/Utilities/Config.h b/Utilities/Config.h index 2a5686a64b..3bba385825 100644 --- a/Utilities/Config.h +++ b/Utilities/Config.h @@ -3,6 +3,8 @@ #include "Utilities/types.h" #include "Utilities/StrFmt.h" #include "Utilities/Log.h" +#include "util/atomic.hpp" +#include "util/shared_cptr.hpp" #include #include @@ -121,10 +123,10 @@ namespace cfg class _bool final : public _base { - bool m_value; + atomic_t m_value; public: - bool def; + const bool def; _bool(node* owner, const std::string& name, bool def = false, bool dynamic = false) : _base(type::_bool, owner, name, dynamic) @@ -138,7 +140,7 @@ namespace cfg return m_value; } - const bool& get() const + bool get() const { return m_value; } @@ -172,7 +174,7 @@ namespace cfg template class _enum final : public _base { - T m_value; + atomic_t m_value; public: const T def; @@ -189,7 +191,7 @@ namespace cfg return m_value; } - const T& get() const + T get() const { return m_value; } @@ -202,7 +204,7 @@ namespace cfg std::string to_string() const override { std::string result; - fmt_class_string::format(result, fmt_unveil::get(m_value)); + fmt_class_string::format(result, fmt_unveil::get(m_value.load())); return result; // TODO: ??? } @@ -235,7 +237,7 @@ namespace cfg // Prefer 32 bit type if possible using int_type = std::conditional_t= INT32_MIN && Max <= INT32_MAX, s32, s64>; - int_type m_value; + atomic_t m_value; public: int_type def; @@ -256,7 +258,7 @@ namespace cfg return m_value; } - const int_type& get() const + int_type get() const { return m_value; } @@ -303,50 +305,56 @@ namespace cfg // Simple string entry with mutex class string final : public _base { - std::string m_name; - std::string m_value; + const std::string m_name; + + stx::atomic_cptr m_value; public: std::string def; - string(node* owner, const std::string& name, const std::string& def = {}, bool dynamic = false) + string(node* owner, std::string name, std::string def = {}, bool dynamic = false) : _base(type::string, owner, name, dynamic) - , m_name(name) - , m_value(def) - , def(def) + , m_name(std::move(name)) + , m_value(m_value.make(def)) + , def(std::move(def)) { } operator std::string() const { - return m_value; + return *m_value.load().get(); } - const std::string& get() const + std::pair> get() const { - return m_value; + auto v = m_value.load(); + + if (auto s = v.get()) + { + return {*s, std::move(v)}; + } + else + { + static const std::string _empty; + return {_empty, {}}; + } } - std::string get_name() const + const std::string& get_name() const { return m_name; } - std::size_t size() const - { - return m_value.size(); - } - void from_default() override; std::string to_string() const override { - return m_value; + return *m_value.load().get(); } bool from_string(const std::string& value, bool /*dynamic*/ = false) override { - m_value = value; + m_value = m_value.make(value); return true; } }; diff --git a/rpcs3/Emu/GDB.cpp b/rpcs3/Emu/GDB.cpp index 071ec489b6..22fb7d4a38 100644 --- a/rpcs3/Emu/GDB.cpp +++ b/rpcs3/Emu/GDB.cpp @@ -116,7 +116,9 @@ void gdb_thread::start_server() // IPv4 address:port in format 127.0.0.1:2345 static const std::regex ipv4_regex("^([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})\\:([0-9]{1,5})$"); - if (g_cfg.misc.gdb_server.get()[0] == '\0') + auto [sname, sshared] = g_cfg.misc.gdb_server.get(); + + if (sname[0] == '\0') { // Empty string or starts with null: GDB server disabled GDB.notice("GDB Server is disabled."); @@ -126,7 +128,7 @@ void gdb_thread::start_server() // Try to detect socket type std::smatch match; - if (std::regex_match(g_cfg.misc.gdb_server.get(), match, ipv4_regex)) + if (std::regex_match(sname, match, ipv4_regex)) { struct addrinfo hints{}; struct addrinfo* info; @@ -142,7 +144,7 @@ void gdb_thread::start_server() if (server_socket == -1) { - GDB.error("Error creating IP socket for '%s'.", g_cfg.misc.gdb_server.get()); + GDB.error("Error creating IP socket for '%s'.", sname); freeaddrinfo(info); return; } @@ -151,7 +153,7 @@ void gdb_thread::start_server() if (bind(server_socket, info->ai_addr, static_cast(info->ai_addrlen)) != 0) { - GDB.error("Failed to bind socket on '%s'.", g_cfg.misc.gdb_server.get()); + GDB.error("Failed to bind socket on '%s'.", sname); freeaddrinfo(info); return; } @@ -160,11 +162,11 @@ void gdb_thread::start_server() if (listen(server_socket, 1) != 0) { - GDB.error("Failed to listen on '%s'.", g_cfg.misc.gdb_server.get()); + GDB.error("Failed to listen on '%s'.", sname); return; } - GDB.notice("Started listening on '%s'.", g_cfg.misc.gdb_server.get()); + GDB.notice("Started listening on '%s'.", sname); return; } } @@ -179,27 +181,27 @@ void gdb_thread::start_server() } // Delete existing socket (TODO?) - fs::remove_file(g_cfg.misc.gdb_server.get()); + fs::remove_file(sname); set_nonblocking(server_socket); sockaddr_un unix_saddr; unix_saddr.sun_family = AF_UNIX; - strcpy_trunc(unix_saddr.sun_path, g_cfg.misc.gdb_server.get()); + strcpy_trunc(unix_saddr.sun_path, sname); if (bind(server_socket, reinterpret_cast(&unix_saddr), sizeof(unix_saddr)) != 0) { - GDB.error("Failed to bind Unix socket '%s'.", g_cfg.misc.gdb_server.get()); + GDB.error("Failed to bind Unix socket '%s'.", sname); return; } if (listen(server_socket, 1) != 0) { - GDB.error("Failed to listen on Unix socket '%s'.", g_cfg.misc.gdb_server.get()); + GDB.error("Failed to listen on Unix socket '%s'.", sname); return; } - GDB.notice("Started listening on Unix socket '%s'.", g_cfg.misc.gdb_server.get()); + GDB.notice("Started listening on Unix socket '%s'.", sname); } int gdb_thread::read(void* buf, int cnt) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index c5beb07a5d..aa50dc67ff 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -1847,12 +1847,16 @@ void Emulator::Stop(bool restart) std::string cfg_root::node_vfs::get(const cfg::string& _cfg, const char* _def) const { - if (_cfg.get().empty()) + auto [spath, sshared] = _cfg.get(); + + if (spath.empty()) { return fs::get_config_dir() + _def; } - return fmt::replace_all(_cfg.get(), "$(EmulatorDir)", emulator_dir.get().empty() ? fs::get_config_dir() : emulator_dir.get()); + auto [semudir, sshared2] = emulator_dir.get(); + + return fmt::replace_all(spath, "$(EmulatorDir)", semudir.empty() ? fs::get_config_dir() : semudir); } s32 error_code::error_report(const fmt_type_info* sup, u64 arg, const fmt_type_info* sup2, u64 arg2)