fix options being reset when gc thread is gcing

This commit is contained in:
2024-01-03 17:58:57 +01:00
parent 4d7f0eee03
commit 112e242903
4 changed files with 32 additions and 6 deletions

View File

@@ -8,7 +8,9 @@
#include <chrono> #include <chrono>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <mutex>
#include <ostream> #include <ostream>
#include <shared_mutex>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@@ -40,6 +42,7 @@ private:
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time = std::chrono::high_resolution_clock::now(); std::chrono::time_point<std::chrono::high_resolution_clock> _start_time = std::chrono::high_resolution_clock::now();
std::reference_wrapper<std::ostream> _out = std::cout; std::reference_wrapper<std::ostream> _out = std::cout;
std::reference_wrapper<std::ostream> _out_err = std::cerr; std::reference_wrapper<std::ostream> _out_err = std::cerr;
std::shared_mutex _mutex;
}; };

View File

@@ -6,10 +6,11 @@
#define PSIL_OPTIONS_H #define PSIL_OPTIONS_H
#include <mutex>
#include <shared_mutex>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <variant> #include <variant>
class Options { class Options {
public: public:
static bool get_bool(const std::string &opt); static bool get_bool(const std::string &opt);
@@ -25,6 +26,7 @@ private:
{"default_log_level", 1U}}; {"default_log_level", 1U}};
std::unordered_map<std::string, std::variant<size_t, bool>> _current = _defaults; std::unordered_map<std::string, std::variant<size_t, bool>> _current = _defaults;
std::shared_mutex _mutex;
}; };

View File

@@ -14,6 +14,7 @@ Logger &Logger::get() {
} }
void Logger::log(const std::string &tag, const std::string &what, int level) { void Logger::log(const std::string &tag, const std::string &what, int level) {
std::shared_lock l(get()._mutex);
int en_level = Options::get_int("default_log_level"); int en_level = Options::get_int("default_log_level");
if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag); if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag);
@@ -31,6 +32,7 @@ void Logger::log(const std::string &tag, const std::string &what, int level) {
} }
void Logger::log(const std::string &tag, const std::function<void(std::ostream &)> &fn, int level) { void Logger::log(const std::string &tag, const std::function<void(std::ostream &)> &fn, int level) {
std::shared_lock l(get()._mutex);
int en_level = Options::get_int("default_log_level"); int en_level = Options::get_int("default_log_level");
if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag); if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag);
@@ -41,7 +43,19 @@ void Logger::log(const std::string &tag, const std::function<void(std::ostream &
log(tag, out.str(), level); log(tag, out.str(), level);
} }
void Logger::set_level(const std::string &tag, int level) { get()._levels[tag] = level; } void Logger::set_level(const std::string &tag, int level) {
void Logger::set_out(std::ostream &out) { get()._out = out; } std::lock_guard l(get()._mutex);
void Logger::set_out_err(std::ostream &out_err) { get()._out_err = out_err; } get()._levels[tag] = level;
void Logger::reset() { get()._levels = {}; } }
void Logger::set_out(std::ostream &out) {
std::lock_guard l(get()._mutex);
get()._out = out;
}
void Logger::set_out_err(std::ostream &out_err) {
std::lock_guard l(get()._mutex);
get()._out_err = out_err;
}
void Logger::reset() {
std::lock_guard l(get()._mutex);
get()._levels = {};
}

View File

@@ -12,26 +12,33 @@ Options &Options::get() {
} }
bool Options::get_bool(const std::string &opt) { bool Options::get_bool(const std::string &opt) {
Options &o = get(); Options &o = get();
std::shared_lock l(o._mutex);
if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt); if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt);
if (!std::holds_alternative<bool>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt); if (!std::holds_alternative<bool>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt);
return std::get<bool>(o._current.at(opt)); return std::get<bool>(o._current.at(opt));
} }
size_t Options::get_int(const std::string &opt) { size_t Options::get_int(const std::string &opt) {
Options &o = get(); Options &o = get();
std::shared_lock l(o._mutex);
if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt); if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt);
if (!std::holds_alternative<size_t>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt); if (!std::holds_alternative<size_t>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt);
return std::get<size_t>(o._current.at(opt)); return std::get<size_t>(o._current.at(opt));
} }
void Options::set_bool(const std::string &opt, bool val) { void Options::set_bool(const std::string &opt, bool val) {
Options &o = get(); Options &o = get();
std::lock_guard l(o._mutex);
if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt); if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt);
if (!std::holds_alternative<bool>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt); if (!std::holds_alternative<bool>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt);
o._current[opt] = val; o._current[opt] = val;
} }
void Options::set_int(const std::string &opt, size_t val) { void Options::set_int(const std::string &opt, size_t val) {
Options &o = get(); Options &o = get();
std::lock_guard l(o._mutex);
if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt); if (_defaults.find(opt) == _defaults.end()) throw std::invalid_argument("Unknown option " + opt);
if (!std::holds_alternative<size_t>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt); if (!std::holds_alternative<size_t>(_defaults.at(opt))) throw std::invalid_argument("Bad option type " + opt);
o._current[opt] = val; o._current[opt] = val;
} }
void Options::reset() { get()._current = _defaults; } void Options::reset() {
std::lock_guard l(get()._mutex);
get()._current = _defaults;
}