mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Make system config thread-safe (almost)
This commit is contained in:
parent
0147bc2c72
commit
0f87c6c7c3
@ -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()
|
||||
|
@ -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 <utility>
|
||||
#include <string>
|
||||
@ -121,10 +123,10 @@ namespace cfg
|
||||
|
||||
class _bool final : public _base
|
||||
{
|
||||
bool m_value;
|
||||
atomic_t<bool> 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 <typename T>
|
||||
class _enum final : public _base
|
||||
{
|
||||
T m_value;
|
||||
atomic_t<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<T>::format(result, fmt_unveil<T>::get(m_value));
|
||||
fmt_class_string<T>::format(result, fmt_unveil<T>::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<Min >= INT32_MIN && Max <= INT32_MAX, s32, s64>;
|
||||
|
||||
int_type m_value;
|
||||
atomic_t<int_type> 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<std::string> 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<const std::string&, stx::shared_cptr<std::string>> 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;
|
||||
}
|
||||
};
|
||||
|
@ -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<int>(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<struct sockaddr*>(&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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user