summaryrefslogtreecommitdiff
path: root/src/common/logging/backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/logging/backend.cpp')
-rw-r--r--src/common/logging/backend.cpp64
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
212private: 217private:
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
297void Start() {
298 Impl::Start();
299}
300
291void DisableLoggingInTests() { 301void DisableLoggingInTests() {
292 initialization_in_progress_suppress_logging = true; 302 initialization_in_progress_suppress_logging = true;
293} 303}