diff --git a/src/MaaCore/Utils/Logger.hpp b/src/MaaCore/Utils/Logger.hpp index cb65a6876b..1f5a126251 100644 --- a/src/MaaCore/Utils/Logger.hpp +++ b/src/MaaCore/Utils/Logger.hpp @@ -143,8 +143,7 @@ public: std::string push(id& i) { i = 0; - if (auto iter = - std::find_if(m_state.rbegin(), m_state.rend(), [](int e) { return e != -1; }); + if (auto iter = std::find_if(m_state.rbegin(), m_state.rend(), [](int e) { return e != -1; }); iter != m_state.rend()) { i = *iter + 1; } @@ -258,13 +257,13 @@ public: console_ostream& operator=(console_ostream&&) = default; console_ostream& operator=(const console_ostream&) = default; - console_ostream(std::ostream& stream) - : m_ofs(stream) + console_ostream(std::ostream& stream) : + m_ofs(stream) { } - console_ostream(std::reference_wrapper stream) - : m_ofs(stream) + console_ostream(std::reference_wrapper stream) : + m_ofs(stream) { } @@ -300,8 +299,8 @@ public: ostreams& operator=(ostreams&&) = default; ostreams& operator=(const ostreams&) = default; - ostreams(Args&&... args) - : m_ofss(std::forward(args)...) + ostreams(Args&&... args) : + m_ofss(std::forward(args)...) { } @@ -326,8 +325,7 @@ public: } template - static void - streams_put(Tuple& t, std::ostream& (*pf)(std::ostream&), std::index_sequence) + static void streams_put(Tuple& t, std::ostream& (*pf)(std::ostream&), std::index_sequence) { ((convert_reference_wrapper(std::get(t)) << pf), ...); } @@ -345,8 +343,8 @@ public: constexpr separator(const separator&) = default; constexpr separator(separator&&) noexcept = default; - constexpr explicit separator(std::string_view s) noexcept - : str(s) + constexpr explicit separator(std::string_view s) noexcept : + str(s) { } @@ -373,8 +371,8 @@ public: constexpr level(const level&) = default; constexpr level(level&&) noexcept = default; - constexpr explicit level(std::string_view s) noexcept - : str(s) + constexpr explicit level(std::string_view s) noexcept : + str(s) { } @@ -423,29 +421,25 @@ public: } template - LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv) - : m_trace_lock(mtx) - , m_ofs(ofs) + LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv) : + m_trace_lock(mtx), + m_ofs(ofs) { *this << lv; } template - LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv, Args&&... buff) - : m_trace_lock(mtx) - , m_ofs(ofs) + LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv, Args&&... buff) : + m_trace_lock(mtx), + m_ofs(ofs) { ((*this << lv) << ... << std::forward(buff)); } template - LogStream( - std::unique_lock&& lock, - _stream_t&& ofs, - Logger::level lv, - Args&&... buff) - : m_trace_lock(std::move(lock)) - , m_ofs(ofs) + LogStream(std::unique_lock&& lock, _stream_t&& ofs, Logger::level lv, Args&&... buff) : + m_trace_lock(std::move(lock)), + m_ofs(ofs) { ((*this << lv) << ... << std::forward(buff)); } @@ -574,9 +568,7 @@ public: template auto operator<<(T&& arg) { - if (!m_ofs || !m_ofs.is_open()) { - m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::app); - } + ensure_opened(); if constexpr (std::same_as>) { #ifdef ASST_DEBUG return LogStream(m_trace_mutex, ostreams { console_ostream(std::cout), m_ofs }, arg); @@ -586,11 +578,7 @@ public: } else { #ifdef ASST_DEBUG - return LogStream( - m_trace_mutex, - ostreams { console_ostream(std::cout), m_ofs }, - level::trace, - arg); + return LogStream(m_trace_mutex, ostreams { console_ostream(std::cout), m_ofs }, level::trace, arg); #else return LogStream(m_trace_mutex, m_ofs, level::trace, arg); #endif @@ -660,9 +648,7 @@ public: if (!lv.is_enabled()) { return; } - if (!m_ofs || !m_ofs.is_open()) { - m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::app); - } + ensure_opened(); (LogStream( std::move(lock), #ifdef ASST_DEBUG @@ -688,20 +674,33 @@ public: private: friend class SingletonHolder; - Logger() - : m_directory(UserDir.get()) + Logger() : + m_directory(UserDir.get()) { std::filesystem::create_directories(m_log_path.parent_path()); rotate(); log_init_info(); } + void ensure_opened() + { + if (m_ofs && m_ofs.is_open()) [[likely]] { + return; + } + + // m_ofs assigned in multiple threads simultaneously can cause double free + std::unique_lock lock { m_trace_mutex }; + if (m_ofs && m_ofs.is_open()) { + return; + } + m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::app); + } + void rotate() const { constexpr uintmax_t MaxLogSize = 4ULL * 1024 * 1024; try { - if (std::filesystem::exists(m_log_path) - && std::filesystem::is_regular_file(m_log_path)) { + if (std::filesystem::exists(m_log_path) && std::filesystem::is_regular_file(m_log_path)) { const uintmax_t log_size = std::filesystem::file_size(m_log_path); if (log_size >= MaxLogSize) { std::filesystem::rename(m_log_path, m_log_bak_path); @@ -750,9 +749,9 @@ inline Logger::level Logger::level::error("ERR"); class LoggerAux { public: - explicit LoggerAux(std::string_view func_name) - : m_func_name(func_name) - , m_start_time(std::chrono::steady_clock::now()) + explicit LoggerAux(std::string_view func_name) : + m_func_name(func_name), + m_start_time(std::chrono::steady_clock::now()) { #ifdef ASST_DEBUG m_id = Logger::get_instance().push @@ -802,8 +801,7 @@ private: #define LogTraceScope LoggerAux _CatVarNameWithLine(_func_aux_) #ifndef _MSC_VER -inline constexpr std::string_view - summarize_pretty_function(std::string_view pf) // can be consteval? +inline constexpr std::string_view summarize_pretty_function(std::string_view pf) // can be consteval? { // unable to handle something like std::function gen_func() const auto paren = pf.find_first_of('(');