IDE: Process Logging : Add annotation in log so that user can see build is still alive and how long external process takes.
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Tue, 02 Mar 2021 09:42:50 +0100
changeset 2730 ce21ce181fdb
parent 2729 4e0cd7806776
child 2731 c6a55270d468
IDE: Process Logging : Add annotation in log so that user can see build is still alive and how long external process takes.
BeremizIDE.py
util/ProcessLogger.py
--- a/BeremizIDE.py	Tue Mar 02 09:28:44 2021 +0100
+++ b/BeremizIDE.py	Tue Mar 02 09:42:50 2021 +0100
@@ -129,6 +129,7 @@
         self.stack = []
         self.LastRefreshTime = gettime()
         self.LastRefreshTimer = None
+        self.refreshPending = False
 
     def write(self, s, style=None):
         self.StackLock.acquire()
@@ -219,6 +220,16 @@
     def isatty(self):
         return False
 
+    def progress(self, text):
+        l = self.output.GetLineCount()-1
+        self.output.AnnotationSetText(l, text)
+        self.output.AnnotationSetVisible(wx.stc.STC_ANNOTATION_BOXED)
+        self.output.AnnotationSetStyle(l, self.black_white)
+        if self.YieldLock.acquire(0):
+            app = wx.GetApp()
+            app.Yield()
+            self.YieldLock.release()
+
 
 ID_FILEMENURECENTPROJECTS = wx.NewId()
 
--- a/util/ProcessLogger.py	Tue Mar 02 09:28:44 2021 +0100
+++ b/util/ProcessLogger.py	Tue Mar 02 09:42:50 2021 +0100
@@ -28,7 +28,8 @@
 import sys
 import subprocess
 import ctypes
-from threading import Timer, Lock, Thread, Semaphore
+import time
+from threading import Timer, Lock, Thread, Semaphore, Condition
 import signal
 
 _debug = os.path.exists("BEREMIZ_DEBUG")
@@ -154,6 +155,10 @@
         self.errt.start()
         self.startsem.release()
 
+        self.spinwakeuplock = Lock()
+        self.spinwakeupcond = Condition(self.spinwakeuplock)
+        self.spinwakeuptimer = None
+
     def output(self, v):
         if v and self.output_encoding:
             v = v.decode(self.output_encoding)
@@ -192,6 +197,7 @@
             self.finish_callback(self, ecode, pid)
         self.errt.join()
         self.finishsem.release()
+        self.spinwakeup()
 
     def kill(self, gently=True):
         # avoid running kill before start is finished
@@ -222,7 +228,22 @@
             if not self.outt.finished and self.kill_it:
                 self.kill()
             self.finishsem.release()
+            self.spinwakeup()
+
+    def spinwakeup(self):
+        with self.spinwakeuplock:
+            if self.spinwakeuptimer is not None:
+                self.spinwakeuptimer.cancel()
+            self.spinwakeuptimer = None
+            self.spinwakeupcond.notify()
 
     def spin(self):
-        self.finishsem.acquire()
+        start = time.time()
+        while not self.finishsem.acquire(0):
+            with self.spinwakeuplock:
+                self.spinwakeuptimer = Timer(0.1, self.spinwakeup)
+                self.spinwakeuptimer.start()
+                self.spinwakeupcond.wait()
+            self.logger.progress("%.3fs"%(time.time() - start))
+
         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]