util/ProcessLogger.py
branchsvghmi
changeset 3173 f85ecfa0916c
parent 2712 a00f41d097f3
child 2733 244598a6a0d6
equal deleted inserted replaced
3172:78ac4915b0f9 3173:f85ecfa0916c
    26 from __future__ import absolute_import
    26 from __future__ import absolute_import
    27 import os
    27 import os
    28 import sys
    28 import sys
    29 import subprocess
    29 import subprocess
    30 import ctypes
    30 import ctypes
    31 from threading import Timer, Lock, Thread, Semaphore
    31 import time
       
    32 from threading import Timer, Lock, Thread, Semaphore, Condition
    32 import signal
    33 import signal
    33 
    34 
    34 _debug = os.path.exists("BEREMIZ_DEBUG")
    35 _debug = os.path.exists("BEREMIZ_DEBUG")
    35 
    36 
    36 class outputThread(Thread):
    37 class outputThread(Thread):
   152             self.Proc.stderr,
   153             self.Proc.stderr,
   153             self.errors)
   154             self.errors)
   154         self.errt.start()
   155         self.errt.start()
   155         self.startsem.release()
   156         self.startsem.release()
   156 
   157 
       
   158         self.spinwakeuplock = Lock()
       
   159         self.spinwakeupcond = Condition(self.spinwakeuplock)
       
   160         self.spinwakeuptimer = None
       
   161 
   157     def output(self, v):
   162     def output(self, v):
   158         if v and self.output_encoding:
   163         if v and self.output_encoding:
   159             v = v.decode(self.output_encoding)
   164             v = v.decode(self.output_encoding)
   160         self.outdata.append(v)
   165         self.outdata.append(v)
   161         self.outlen += 1
   166         self.outlen += 1
   190             self.log_the_end(ecode, pid)
   195             self.log_the_end(ecode, pid)
   191         if self.finish_callback is not None:
   196         if self.finish_callback is not None:
   192             self.finish_callback(self, ecode, pid)
   197             self.finish_callback(self, ecode, pid)
   193         self.errt.join()
   198         self.errt.join()
   194         self.finishsem.release()
   199         self.finishsem.release()
       
   200         self.spinwakeup()
   195 
   201 
   196     def kill(self, gently=True):
   202     def kill(self, gently=True):
   197         # avoid running kill before start is finished
   203         # avoid running kill before start is finished
   198         self.startsem.acquire()
   204         self.startsem.acquire()
   199         self.startsem.release()
   205         self.startsem.release()
   220     def endlog(self):
   226     def endlog(self):
   221         if self.endlock.acquire(False):
   227         if self.endlock.acquire(False):
   222             if not self.outt.finished and self.kill_it:
   228             if not self.outt.finished and self.kill_it:
   223                 self.kill()
   229                 self.kill()
   224             self.finishsem.release()
   230             self.finishsem.release()
       
   231             self.spinwakeup()
       
   232 
       
   233     def spinwakeup(self):
       
   234         with self.spinwakeuplock:
       
   235             if self.spinwakeuptimer is not None:
       
   236                 self.spinwakeuptimer.cancel()
       
   237             self.spinwakeuptimer = None
       
   238             self.spinwakeupcond.notify()
   225 
   239 
   226     def spin(self):
   240     def spin(self):
   227         self.finishsem.acquire()
   241         start = time.time()
       
   242         while not self.finishsem.acquire(0):
       
   243             with self.spinwakeuplock:
       
   244                 self.spinwakeuptimer = Timer(0.1, self.spinwakeup)
       
   245                 self.spinwakeuptimer.start()
       
   246                 self.spinwakeupcond.wait()
       
   247             self.logger.progress("%.3fs"%(time.time() - start))
       
   248 
   228         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]
   249         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]