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.
This commit is contained in:
parent
fe027a96fb
commit
197c1adcba
|
@ -178,6 +178,7 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) {
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
Common::Log::Initialize();
|
Common::Log::Initialize();
|
||||||
Common::Log::SetColorConsoleBackendEnabled(true);
|
Common::Log::SetColorConsoleBackendEnabled(true);
|
||||||
|
Common::Log::Start();
|
||||||
Common::DetachedTasks detached_tasks;
|
Common::DetachedTasks detached_tasks;
|
||||||
Config config;
|
Config config;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
|
@ -264,6 +264,8 @@ GMainWindow::GMainWindow(Core::System& system_)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Common::Log::Start();
|
||||||
|
|
||||||
QStringList args = QApplication::arguments();
|
QStringList args = QApplication::arguments();
|
||||||
if (args.length() >= 2) {
|
if (args.length() >= 2) {
|
||||||
BootGame(args[1]);
|
BootGame(args[1]);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
@ -31,6 +30,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/logging/log_entry.h"
|
#include "common/logging/log_entry.h"
|
||||||
#include "common/logging/text_formatter.h"
|
#include "common/logging/text_formatter.h"
|
||||||
|
#include "common/polyfill_thread.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
@ -219,6 +219,10 @@ public:
|
||||||
initialization_in_progress_suppress_logging = false;
|
initialization_in_progress_suppress_logging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Start() {
|
||||||
|
instance->StartBackendThread();
|
||||||
|
}
|
||||||
|
|
||||||
Impl(const Impl&) = delete;
|
Impl(const Impl&) = delete;
|
||||||
Impl& operator=(const Impl&) = delete;
|
Impl& operator=(const Impl&) = delete;
|
||||||
|
|
||||||
|
@ -244,26 +248,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Impl(const std::string& file_backend_filename, const Filter& filter_)
|
Impl(const std::string& file_backend_filename, const Filter& filter_)
|
||||||
: filter{filter_}, file_backend{file_backend_filename}, backend_thread{std::thread([this] {
|
: filter{filter_}, file_backend{file_backend_filename} {
|
||||||
Common::SetCurrentThreadName("citra: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();
|
|
||||||
}
|
|
||||||
})} {
|
|
||||||
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
||||||
int waker_pipefd[2];
|
int waker_pipefd[2];
|
||||||
int done_printing_pipefd[2];
|
int done_printing_pipefd[2];
|
||||||
|
@ -297,7 +282,7 @@ private:
|
||||||
}
|
}
|
||||||
line.pop_back(); // Remove newline
|
line.pop_back(); // Remove newline
|
||||||
const auto frame_entry =
|
const auto frame_entry =
|
||||||
CreateEntry(Class::Log, Level::Critical, "?", 0, "?", line);
|
CreateEntry(Class::Log, Level::Critical, "?", 0, "?", std::move(line));
|
||||||
ForEachBackend([&frame_entry](Backend& backend) { backend.Write(frame_entry); });
|
ForEachBackend([&frame_entry](Backend& backend) { backend.Write(frame_entry); });
|
||||||
}
|
}
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
@ -326,15 +311,35 @@ private:
|
||||||
StopBackendThread();
|
StopBackendThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StartBackendThread() {
|
||||||
|
backend_thread = std::thread([this] {
|
||||||
|
Common::SetCurrentThreadName("citra: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() {
|
void StopBackendThread() {
|
||||||
Entry stop_entry{};
|
stop.request_stop();
|
||||||
stop_entry.final_entry = true;
|
|
||||||
message_queue.Push(stop_entry);
|
|
||||||
backend_thread.join();
|
backend_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
|
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::duration_cast;
|
||||||
using std::chrono::microseconds;
|
using std::chrono::microseconds;
|
||||||
using std::chrono::steady_clock;
|
using std::chrono::steady_clock;
|
||||||
|
@ -347,7 +352,6 @@ private:
|
||||||
.line_num = line_nr,
|
.line_num = line_nr,
|
||||||
.function = function,
|
.function = function,
|
||||||
.message = std::move(message),
|
.message = std::move(message),
|
||||||
.final_entry = false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,8 +402,9 @@ private:
|
||||||
ColorConsoleBackend color_console_backend{};
|
ColorConsoleBackend color_console_backend{};
|
||||||
FileBackend file_backend;
|
FileBackend file_backend;
|
||||||
|
|
||||||
|
std::stop_source stop;
|
||||||
std::thread backend_thread;
|
std::thread backend_thread;
|
||||||
MPSCQueue<Entry> message_queue{};
|
MPSCQueue<Entry, true> message_queue{};
|
||||||
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
|
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
|
||||||
|
|
||||||
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
||||||
|
@ -415,6 +420,10 @@ void Initialize() {
|
||||||
Impl::Initialize();
|
Impl::Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
Impl::Start();
|
||||||
|
}
|
||||||
|
|
||||||
void DisableLoggingInTests() {
|
void DisableLoggingInTests() {
|
||||||
initialization_in_progress_suppress_logging = true;
|
initialization_in_progress_suppress_logging = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ class Filter;
|
||||||
/// Initializes the logging system. This should be the first thing called in main.
|
/// Initializes the logging system. This should be the first thing called in main.
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
|
void Start();
|
||||||
|
|
||||||
void DisableLoggingInTests();
|
void DisableLoggingInTests();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,6 @@ struct Entry {
|
||||||
unsigned int line_num = 0;
|
unsigned int line_num = 0;
|
||||||
std::string function;
|
std::string function;
|
||||||
std::string message;
|
std::string message;
|
||||||
bool final_entry = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Common::Log
|
} // namespace Common::Log
|
||||||
|
|
Reference in New Issue