From d6b5f64484053772c486a0cd4d3be98f02a01391 Mon Sep 17 00:00:00 2001 From: Levi Behunin Date: Mon, 1 Nov 2021 18:36:27 -0600 Subject: Refactor Logging Impl Loop on stop_token and remove final_entry in Entry. Move Backend thread out of Impl Constructor to its own function. Add Start function for backend thread. Use stop token in PopWait and check if entry filename is nullptr before logging. --- src/common/logging/backend.cpp | 64 ++++++++++++++++++++++++------------------ src/common/logging/backend.h | 2 ++ src/common/logging/log_entry.h | 1 - src/yuzu/main.cpp | 2 ++ 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 0e85a9c1d..c51c05b28 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -186,6 +187,10 @@ public: initialization_in_progress_suppress_logging = false; } + static void Start() { + instance->StartBackendThread(); + } + Impl(const Impl&) = delete; Impl& operator=(const Impl&) = delete; @@ -201,7 +206,7 @@ public: } void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, std::string message) { + const char* function, std::string&& message) { if (!filter.CheckMessage(log_class, log_level)) return; const Entry& entry = @@ -211,40 +216,41 @@ public: private: Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) - : filter{filter_}, file_backend{file_backend_filename}, backend_thread{std::thread([this] { - Common::SetCurrentThreadName("yuzu:Log"); - Entry entry; - const auto write_logs = [this, &entry]() { - ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); - }; - while (true) { - entry = message_queue.PopWait(); - if (entry.final_entry) { - break; - } - write_logs(); - } - // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a - // case where a system is repeatedly spamming logs even on close. - int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100; - while (max_logs_to_write-- && message_queue.Pop(entry)) { - write_logs(); - } - })} {} + : filter{filter_}, file_backend{file_backend_filename} {} ~Impl() { StopBackendThread(); } + void StartBackendThread() { + backend_thread = std::thread([this] { + Common::SetCurrentThreadName("yuzu:Log"); + Entry entry; + const auto write_logs = [this, &entry]() { + ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); + }; + while (!stop.stop_requested()) { + entry = message_queue.PopWait(stop.get_token()); + if (entry.filename != nullptr) { + write_logs(); + } + } + // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a + // case where a system is repeatedly spamming logs even on close. + int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100; + while (max_logs_to_write-- && message_queue.Pop(entry)) { + write_logs(); + } + }); + } + void StopBackendThread() { - Entry stop_entry{}; - stop_entry.final_entry = true; - message_queue.Push(stop_entry); + stop.request_stop(); backend_thread.join(); } Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, - const char* function, std::string message) const { + const char* function, std::string&& message) const { using std::chrono::duration_cast; using std::chrono::microseconds; using std::chrono::steady_clock; @@ -257,7 +263,6 @@ private: .line_num = line_nr, .function = function, .message = std::move(message), - .final_entry = false, }; } @@ -278,8 +283,9 @@ private: ColorConsoleBackend color_console_backend{}; FileBackend file_backend; + std::stop_source stop; std::thread backend_thread; - MPSCQueue message_queue{}; + MPSCQueue message_queue{}; std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; }; } // namespace @@ -288,6 +294,10 @@ void Initialize() { Impl::Initialize(); } +void Start() { + Impl::Start(); +} + void DisableLoggingInTests() { initialization_in_progress_suppress_logging = true; } diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index cb7839ee9..bf785f402 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h @@ -14,6 +14,8 @@ class Filter; /// Initializes the logging system. This should be the first thing called in main. void Initialize(); +void Start(); + void DisableLoggingInTests(); /** diff --git a/src/common/logging/log_entry.h b/src/common/logging/log_entry.h index dd6f44841..b28570071 100644 --- a/src/common/logging/log_entry.h +++ b/src/common/logging/log_entry.h @@ -22,7 +22,6 @@ struct Entry { unsigned int line_num = 0; std::string function; std::string message; - bool final_entry = false; }; } // namespace Common::Log diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e871fee36..182b486e9 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -299,6 +299,8 @@ GMainWindow::GMainWindow() SDL_EnableScreenSaver(); #endif + Common::Log::Start(); + QStringList args = QApplication::arguments(); if (args.size() < 2) { -- cgit v1.2.3