[geary/wip/structured-logging] Ensure logging system is thread-safe



commit 95e856b664ab1acee79f662cae72b9f3b72b471d
Author: Michael Gratton <mike vee net>
Date:   Sun Jun 30 16:27:48 2019 +1000

    Ensure logging system is thread-safe
    
    Use a mutex to log when outputting debug log lines, ensure the listener
    (if any) is invoked on the main loop.

 src/engine/api/geary-logging.vala | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
---
diff --git a/src/engine/api/geary-logging.vala b/src/engine/api/geary-logging.vala
index 52379962..3d95a8c7 100644
--- a/src/engine/api/geary-logging.vala
+++ b/src/engine/api/geary-logging.vala
@@ -326,6 +326,8 @@ private Flag logging_flags = Flag.NONE;
 private unowned FileStream? stream = null;
 private Timer? entry_timer = null;
 
+// Can't be nullable. See https://gitlab.gnome.org/GNOME/vala/issues/812
+private GLib.Mutex record_lock;
 private Record? first_record = null;
 private Record? last_record = null;
 private uint log_length = 0;
@@ -344,6 +346,7 @@ public void init() {
     if (init_count++ != 0)
         return;
     entry_timer = new Timer();
+    record_lock = GLib.Mutex();
     max_log_length = DEFAULT_MAX_LOG_BUFFER_LENGTH;
 }
 
@@ -449,6 +452,10 @@ public void log_to(FileStream? stream) {
 
 public GLib.LogWriterOutput default_log_writer(GLib.LogLevelFlags levels,
                                                GLib.LogField[] fields) {
+    // Obtain a lock since multiple threads can be calling this
+    // function at the same time
+    record_lock.lock();
+
     Record record = new Record(
         fields,
         levels,
@@ -475,7 +482,10 @@ public GLib.LogWriterOutput default_log_writer(GLib.LogLevelFlags levels,
     }
 
     if (listener != null) {
-        listener(record);
+        GLib.MainContext.default().invoke(() => {
+                listener(record);
+                return GLib.Source.REMOVE;
+            });
     }
 
     // Print a log message to the stream
@@ -493,6 +503,8 @@ public GLib.LogWriterOutput default_log_writer(GLib.LogLevelFlags levels,
         out.putc('\n');
     }
 
+    record_lock.unlock();
+
     return GLib.LogWriterOutput.HANDLED;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]