From 87bc5266ef14acf41f0751873cca469ef7e2e01b Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 23 Feb 2018 00:33:44 -0700 Subject: [PATCH] Logging: Various logging improvements * Uses PopWait to reduce the amount of busy waiting if there aren't many new logs * Opens the log file as shared on windows, letting other programs read the logs, but not write to them while citra is running * Flushes the logs to disk if a log >= error arrives --- src/common/file_util.cpp | 15 ++++++++++----- src/common/file_util.h | 5 +++-- src/common/logging/backend.cpp | 15 +++++++++++++-- src/common/logging/backend.h | 5 +++-- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 446bd4398c..7b256fede4 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -803,8 +803,8 @@ void SplitFilename83(const std::string& filename, std::array& short_nam IOFile::IOFile() {} -IOFile::IOFile(const std::string& filename, const char openmode[]) { - Open(filename, openmode); +IOFile::IOFile(const std::string& filename, const char openmode[], int flags) { + Open(filename, openmode, flags); } IOFile::~IOFile() { @@ -825,11 +825,16 @@ void IOFile::Swap(IOFile& other) { std::swap(m_good, other.m_good); } -bool IOFile::Open(const std::string& filename, const char openmode[]) { +bool IOFile::Open(const std::string& filename, const char openmode[], int flags) { Close(); #ifdef _WIN32 - _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), - Common::UTF8ToUTF16W(openmode).c_str()); + if (flags != 0) { + m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(), + Common::UTF8ToUTF16W(openmode).c_str(), flags); + } else { + _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), + Common::UTF8ToUTF16W(openmode).c_str()); + } #else m_file = fopen(filename.c_str(), openmode); #endif diff --git a/src/common/file_util.h b/src/common/file_util.h index 0912349773..8674ac2249 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -156,7 +156,8 @@ void SplitFilename83(const std::string& filename, std::array& short_nam class IOFile : public NonCopyable { public: IOFile(); - IOFile(const std::string& filename, const char openmode[]); + /// Opens the file. flags is for windows shared file settings and are ignored on other oses + IOFile(const std::string& filename, const char openmode[], int flags = 0); ~IOFile(); @@ -165,7 +166,7 @@ public: void Swap(IOFile& other); - bool Open(const std::string& filename, const char openmode[]); + bool Open(const std::string& filename, const char openmode[], int flags = 0); bool Close(); template diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 4d80fd8e24..cae48d9f3a 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -9,6 +9,11 @@ #include #include #include +#ifdef _WIN32 +#include // For _SH_DENYWR +#else +#define _SH_DENYWR 0 +#endif #include "common/assert.h" #include "common/common_funcs.h" // snprintf compatibility define #include "common/logging/backend.h" @@ -68,8 +73,7 @@ private: using namespace std::chrono_literals; Entry entry; while (running) { - if (!message_queue.Pop(entry)) { - std::this_thread::sleep_for(1ms); + if (!message_queue.PopWait(entry)) { continue; } for (const auto& backend : backends) { @@ -97,11 +101,18 @@ void ColorConsoleBackend::Write(const Entry& entry) { PrintColoredMessage(entry); } +// _SH_DENYWR allows read only access to the file for other programs. +// It is #defined to 0 on other platforms +FileBackend::FileBackend(const std::string& filename) : file(filename, "w", _SH_DENYWR) {} + void FileBackend::Write(const Entry& entry) { if (!file.IsOpen()) { return; } file.WriteString(FormatLogMessage(entry) + '\n'); + if (entry.log_level >= Level::Error) { + file.Flush(); + } } /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index dfa4944f40..5feef5dd45 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h @@ -78,11 +78,12 @@ public: }; /** - * Backend that writes to a file passed into the constructor + * Backend that writes to a file passed into the constructor. If a log level is error or higher, it + * will flush immediately after writing */ class FileBackend : public Backend { public: - explicit FileBackend(const std::string& filename) : file(filename, "w") {} + explicit FileBackend(const std::string& filename); const char* GetName() const override { return "file";