diff options
Diffstat (limited to 'src/common/logging/backend.cpp')
| -rw-r--r-- | src/common/logging/backend.cpp | 64 |
1 files changed, 37 insertions, 27 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 @@ | |||
| 6 | #include <chrono> | 6 | #include <chrono> |
| 7 | #include <climits> | 7 | #include <climits> |
| 8 | #include <exception> | 8 | #include <exception> |
| 9 | #include <stop_token> | ||
| 9 | #include <thread> | 10 | #include <thread> |
| 10 | #include <vector> | 11 | #include <vector> |
| 11 | 12 | ||
| @@ -186,6 +187,10 @@ public: | |||
| 186 | initialization_in_progress_suppress_logging = false; | 187 | initialization_in_progress_suppress_logging = false; |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 190 | static void Start() { | ||
| 191 | instance->StartBackendThread(); | ||
| 192 | } | ||
| 193 | |||
| 189 | Impl(const Impl&) = delete; | 194 | Impl(const Impl&) = delete; |
| 190 | Impl& operator=(const Impl&) = delete; | 195 | Impl& operator=(const Impl&) = delete; |
| 191 | 196 | ||
| @@ -201,7 +206,7 @@ public: | |||
| 201 | } | 206 | } |
| 202 | 207 | ||
| 203 | void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, | 208 | void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, |
| 204 | const char* function, std::string message) { | 209 | const char* function, std::string&& message) { |
| 205 | if (!filter.CheckMessage(log_class, log_level)) | 210 | if (!filter.CheckMessage(log_class, log_level)) |
| 206 | return; | 211 | return; |
| 207 | const Entry& entry = | 212 | const Entry& entry = |
| @@ -211,40 +216,41 @@ public: | |||
| 211 | 216 | ||
| 212 | private: | 217 | private: |
| 213 | Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) | 218 | Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) |
| 214 | : filter{filter_}, file_backend{file_backend_filename}, backend_thread{std::thread([this] { | 219 | : filter{filter_}, file_backend{file_backend_filename} {} |
| 215 | Common::SetCurrentThreadName("yuzu:Log"); | ||
| 216 | Entry entry; | ||
| 217 | const auto write_logs = [this, &entry]() { | ||
| 218 | ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); | ||
| 219 | }; | ||
| 220 | while (true) { | ||
| 221 | entry = message_queue.PopWait(); | ||
| 222 | if (entry.final_entry) { | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | write_logs(); | ||
| 226 | } | ||
| 227 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a | ||
| 228 | // case where a system is repeatedly spamming logs even on close. | ||
| 229 | int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100; | ||
| 230 | while (max_logs_to_write-- && message_queue.Pop(entry)) { | ||
| 231 | write_logs(); | ||
| 232 | } | ||
| 233 | })} {} | ||
| 234 | 220 | ||
| 235 | ~Impl() { | 221 | ~Impl() { |
| 236 | StopBackendThread(); | 222 | StopBackendThread(); |
| 237 | } | 223 | } |
| 238 | 224 | ||
| 225 | void StartBackendThread() { | ||
| 226 | backend_thread = std::thread([this] { | ||
| 227 | Common::SetCurrentThreadName("yuzu:Log"); | ||
| 228 | Entry entry; | ||
| 229 | const auto write_logs = [this, &entry]() { | ||
| 230 | ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); | ||
| 231 | }; | ||
| 232 | while (!stop.stop_requested()) { | ||
| 233 | entry = message_queue.PopWait(stop.get_token()); | ||
| 234 | if (entry.filename != nullptr) { | ||
| 235 | write_logs(); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a | ||
| 239 | // case where a system is repeatedly spamming logs even on close. | ||
| 240 | int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100; | ||
| 241 | while (max_logs_to_write-- && message_queue.Pop(entry)) { | ||
| 242 | write_logs(); | ||
| 243 | } | ||
| 244 | }); | ||
| 245 | } | ||
| 246 | |||
| 239 | void StopBackendThread() { | 247 | void StopBackendThread() { |
| 240 | Entry stop_entry{}; | 248 | stop.request_stop(); |
| 241 | stop_entry.final_entry = true; | ||
| 242 | message_queue.Push(stop_entry); | ||
| 243 | backend_thread.join(); | 249 | backend_thread.join(); |
| 244 | } | 250 | } |
| 245 | 251 | ||
| 246 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | 252 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, |
| 247 | const char* function, std::string message) const { | 253 | const char* function, std::string&& message) const { |
| 248 | using std::chrono::duration_cast; | 254 | using std::chrono::duration_cast; |
| 249 | using std::chrono::microseconds; | 255 | using std::chrono::microseconds; |
| 250 | using std::chrono::steady_clock; | 256 | using std::chrono::steady_clock; |
| @@ -257,7 +263,6 @@ private: | |||
| 257 | .line_num = line_nr, | 263 | .line_num = line_nr, |
| 258 | .function = function, | 264 | .function = function, |
| 259 | .message = std::move(message), | 265 | .message = std::move(message), |
| 260 | .final_entry = false, | ||
| 261 | }; | 266 | }; |
| 262 | } | 267 | } |
| 263 | 268 | ||
| @@ -278,8 +283,9 @@ private: | |||
| 278 | ColorConsoleBackend color_console_backend{}; | 283 | ColorConsoleBackend color_console_backend{}; |
| 279 | FileBackend file_backend; | 284 | FileBackend file_backend; |
| 280 | 285 | ||
| 286 | std::stop_source stop; | ||
| 281 | std::thread backend_thread; | 287 | std::thread backend_thread; |
| 282 | MPSCQueue<Entry> message_queue{}; | 288 | MPSCQueue<Entry, true> message_queue{}; |
| 283 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; | 289 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; |
| 284 | }; | 290 | }; |
| 285 | } // namespace | 291 | } // namespace |
| @@ -288,6 +294,10 @@ void Initialize() { | |||
| 288 | Impl::Initialize(); | 294 | Impl::Initialize(); |
| 289 | } | 295 | } |
| 290 | 296 | ||
| 297 | void Start() { | ||
| 298 | Impl::Start(); | ||
| 299 | } | ||
| 300 | |||
| 291 | void DisableLoggingInTests() { | 301 | void DisableLoggingInTests() { |
| 292 | initialization_in_progress_suppress_logging = true; | 302 | initialization_in_progress_suppress_logging = true; |
| 293 | } | 303 | } |