[chronojump] Logs are synced between threads and only printed by main thread (solving set.out -> streamwriter not



commit 295d66b6c0365ab78b47098f362d8d6e75dc9d23
Author: Xavier de Blas <xaviblas gmail com>
Date:   Fri Aug 5 09:08:57 2016 +0200

    Logs are synced between threads and only printed by main thread (solving set.out -> streamwriter not 
threadsafe)

 src/chronojump.cs   |    1 +
 src/encoderRProc.cs |    2 +-
 src/gui/encoder.cs  |    2 +-
 src/logB.cs         |   95 +++++++++++++++++++++++++++++++++++++--------------
 4 files changed, 72 insertions(+), 28 deletions(-)
---
diff --git a/src/chronojump.cs b/src/chronojump.cs
index 802db3a..60d9302 100644
--- a/src/chronojump.cs
+++ b/src/chronojump.cs
@@ -69,6 +69,7 @@ public class ChronoJump
                Log.WriteLine(string.Format("Client database option 2 in ... " + Util.GetDatabaseTempDir()));
                */
                
+               LogSync.Initialize();
                //1.4.10
                Log.Start();
                LogB.Debugging = true; //now LogB.Debug will be shown. Also there will be thread info on 
Warning, Error, Information
diff --git a/src/encoderRProc.cs b/src/encoderRProc.cs
index 5a3e8c7..1fabd22 100644
--- a/src/encoderRProc.cs
+++ b/src/encoderRProc.cs
@@ -310,7 +310,7 @@ public class EncoderRProcCapture : EncoderRProc
                /*
                 * curveCompressed print has made crash Chronojump once.
                 * Seems to be a problem with multithreading and Console.SetOut, see logB Commit (added a 
try/catch there)
-                * until is not fixed, better leave this commented
+                * on 2016 August 5 (1.6.2) should be fixed with LogSync class, but for now better leave this 
commented until more tests are done
                 */
                //LogB.Information("curveSend [displacement array]",curveCompressed);
 
diff --git a/src/gui/encoder.cs b/src/gui/encoder.cs
index 938a3f9..4fe48f9 100644
--- a/src/gui/encoder.cs
+++ b/src/gui/encoder.cs
@@ -5657,7 +5657,7 @@ public partial class ChronoJumpWindow
                Util.FileDelete(UtilEncoder.GetEncoderStatusTempBaseFileName() + "6.txt");
                        
                //for chronojumpWindowTests
-               LogB.Error("finishPulseBar DONE: " + action.ToString());
+               LogB.Information("finishPulseBar DONE: " + action.ToString());
                if(
                                action == encoderActions.LOAD ||        //load 
                                action == encoderActions.CURVES )       //recalculate
diff --git a/src/logB.cs b/src/logB.cs
index 1e32bf6..0db8ec4 100644
--- a/src/logB.cs
+++ b/src/logB.cs
@@ -103,6 +103,48 @@ public class LogEntry
        }
 }
 
+/*
+ * LogB Console.Write is written to a file. see log.Start() at log.cs
+ * is done by
+ *     System.Console.SetOut(sw);
+ *     System.Console.SetError(sw);
+ *     sw.AutoFlush = true;
+ * and this is not threadsafe.
+ * We store a string on this class with the Log that will be pushed to Console -> StreamWriter, only by the 
main thread
+ */
+// Based on O'Reilly C# Cookbook p. 1015
+public static class LogSync
+{
+       private static string logPending;
+       private static object syncObj = new object();
+
+       //only called one time (at Chronojump Main())
+       public static void Initialize()
+       {
+               logPending = "";
+       }
+
+       //called by threads 2 and above
+       public static void Add(string str)
+       {
+               lock(syncObj)
+               {
+                       logPending += str;
+               }
+       }
+       
+       //called by thread 1 (GTK)
+       public static string ReadAndEmpty()
+       {
+               lock(syncObj)
+               {
+                       string str = logPending;
+                       logPending = "";
+                       return str;
+               }
+       }
+}
+
 //copied from Banshee project
 //called LogB because in Chronojump there's already a Log class that will be deprecated soon
 public static class LogB
@@ -179,39 +221,40 @@ public static class LogB
                        }
 
                        var thread_name = String.Empty;
+                       bool printNow = false;
                        if(Debugging) {
                                var thread = Thread.CurrentThread;
                                thread_name = thread.ManagedThreadId.ToString();
-                               if(thread_name == "1")
+                               if(thread_name == "1") {
+                                       printNow = true;
                                        thread_name = "1-GTK ";
-                               else
+                               } else 
                                        thread_name += "     ";
                        }
 
-                       /*
-                        * TODO: Console.Write is written to a file. see log.Start() at log.cs
-                        * is done by 
-                        *      System.Console.SetOut(sw);
-                        *      System.Console.SetError(sw);
-                        *      sw.AutoFlush = true;
-                        * and this is not threadsafe. 
-                        * Have to find a way using TextWriter.Synchronized http://stackoverflow.com/a/9539571
-                        */
-                       try {
-                               Console.Write("[{5}{0} {1:00}:{2:00}:{3:00}.{4:000}]", TypeString(type), 
DateTime.Now.Hour,
-                                               DateTime.Now.Minute, DateTime.Now.Second, 
DateTime.Now.Millisecond, thread_name);
-
-                               ConsoleCrayon.ResetColor();
-
-                               if(details != null) {
-                                       Console.WriteLine(" {0} - {1}", message, details);
-                               } else {
-                                       if(type == LogEntryType.Debug)
-                                               Console.Write(" {0}", message);
-                                       else
-                                               Console.WriteLine(" {0}", message);
-                               }
-                       } catch (System.IndexOutOfRangeException e) {
+                       string lineStart = string.Format("[{5}{0} {1:00}:{2:00}:{3:00}.{4:000}]", 
TypeString(type), DateTime.Now.Hour,
+                                       DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond, 
thread_name);
+
+                       if(printNow) {
+                               //try {
+                                       Console.Write(lineStart);
+       
+                                       ConsoleCrayon.ResetColor();
+       
+                                       message += LogSync.ReadAndEmpty();
+       
+                                       if(details != null) {
+                                               Console.WriteLine(" {0} - {1}", message, details);
+                                       } else {
+                                               if(type == LogEntryType.Debug)
+                                                       Console.Write(" {0}", message);
+                                               else
+                                                       Console.WriteLine(" {0}", message);
+                                       }
+                               //} catch (System.IndexOutOfRangeException e) {
+                               //}
+                       } else {
+                               LogSync.Add(lineStart + "\n" + message);
                        }
                }
 


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