--- a/Beremiz.py Sat Mar 31 15:10:55 2012 +0200
+++ b/Beremiz.py Sat Mar 31 15:20:04 2012 +0200
@@ -284,7 +284,8 @@
dc.DrawBitmap(self._bitmap, 0, 0, True)
-from threading import Lock,Timer
+from threading import Lock,Timer,currentThread
+MainThread = currentThread().ident
REFRESH_PERIOD = 0.1
from time import time as gettime
class LogPseudoFile:
@@ -299,6 +300,7 @@
# to prevent rapid fire on rising log panel
self.rising_timer = 0
self.lock = Lock()
+ self.YieldLock = Lock()
self.RefreshLock = Lock()
self.stack = []
self.LastRefreshTime = gettime()
@@ -313,11 +315,20 @@
self.LastRefreshTimer.cancel()
self.LastRefreshTimer=None
if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False):
- wx.CallAfter(self._write)
+ self._should_write()
else:
- self.LastRefreshTimer = Timer(REFRESH_PERIOD, wx.CallAfter, [self._write])
+ self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._should_write)
self.LastRefreshTimer.start()
+ def _should_write(self):
+ wx.CallAfter(self._write)
+ if MainThread == currentThread().ident:
+ app = wx.GetApp()
+ if app is not None:
+ if self.YieldLock.acquire(0):
+ app.Yield()
+ self.YieldLock.release()
+
def _write(self):
if self.output :
self.output.Freeze();
@@ -587,8 +598,9 @@
self.runtime_port,
{False : "-x 0", True :"-x 1"}[taskbaricon],
self.local_runtime_tmpdir),
- no_gui=False)
- self.local_runtime.spin(timeout=500, keyword = "working", kill_it = False)
+ no_gui=False,
+ timeout=500, keyword = "working")
+ self.local_runtime.spin()
return self.runtime_port
def KillLocalRuntime(self):
--- a/wxPopen.py Sat Mar 31 15:10:55 2012 +0200
+++ b/wxPopen.py Sat Mar 31 15:20:04 2012 +0200
@@ -26,18 +26,18 @@
import time
import wx
import subprocess, ctypes
-import threading
+from threading import Timer, Lock, Thread, Semaphore
import os
if os.name == 'posix':
from signal import SIGTERM, SIGKILL
-class outputThread(threading.Thread):
+class outputThread(Thread):
"""
Thread is used to print the output of a command to the stdout
"""
def __init__(self, Proc, fd, callback=None, endcallback=None):
- threading.Thread.__init__(self)
+ Thread.__init__(self)
self.killed = False
self.finished = False
self.retval = None
@@ -58,6 +58,7 @@
if self.callback : self.callback(outchunk)
while outchunk != '' and not self.killed :
outchunk = self.fd.readline()
+ if self.callback : self.callback(outchunk)
if self.endcallback:
try:
err = self.Proc.wait()
@@ -67,7 +68,10 @@
self.endcallback(self.Proc.pid, err)
class ProcessLogger:
- def __init__(self, logger, Command, finish_callback=None, no_stdout=False, no_stderr=False, no_gui=True):
+ def __init__(self, logger, Command, finish_callback = None,
+ no_stdout = False, no_stderr = False, no_gui = True,
+ timeout = None, outlimit = None, errlimit = None,
+ endlog = None, keyword = None, kill_it = False):
self.logger = logger
if not isinstance(Command, list):
self.Command_str = Command
@@ -89,10 +93,15 @@
self.startupinfo = None
self.errlen = 0
self.outlen = 0
+ self.errlimit = errlimit
+ self.outlimit = outlimit
self.exitcode = None
- self.outdata = ""
- self.errdata = ""
- self.finished = False
+ self.outdata = []
+ self.errdata = []
+ self.keyword = keyword
+ self.kill_it = kill_it
+ self.finishsem = Semaphore(0)
+ self.endlock = Lock()
popenargs= {
"cwd":os.getcwd(),
@@ -105,7 +114,7 @@
self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
popenargs["startupinfo"] = self.startupinfo
elif wx.Platform == '__WXGTK__':
- popenargs["shell"] = False #True
+ popenargs["shell"] = False
self.Proc = subprocess.Popen( self.Command, **popenargs )
@@ -122,29 +131,35 @@
self.errors)
self.errt.start()
+ Timer(timeout,self.endlog).start()
+
def output(self,v):
- self.outdata += v
+ self.outdata.append(v)
self.outlen += 1
if not self.no_stdout:
self.logger.write(v)
+ if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit):
+ self.endlog()
def errors(self,v):
- self.errdata += v
+ self.errdata.append(v)
self.errlen += 1
if not self.no_stderr:
self.logger.write_warning(v)
+ if self.errlimit and self.errlen > self.errlimit:
+ self.endlog()
def log_the_end(self,ecode,pid):
self.logger.write(self.Command_str + "\n")
self.logger.write_warning(_("exited with status %s (pid %s)\n")%(str(ecode),str(pid)))
def finish(self, pid,ecode):
- self.finished = True
self.exitcode = ecode
if self.exitcode != 0:
self.log_the_end(ecode,pid)
if self.finish_callback is not None:
self.finish_callback(self,ecode,pid)
+ self.finishsem.release()
def kill(self,gently=True):
self.outt.killed = True
@@ -166,26 +181,14 @@
self.outt.join()
self.errt.join()
- def spin(self, timeout=None, out_limit=None, err_limit=None, keyword = None, kill_it = True):
- count = 0
- while not self.finished:
- if err_limit and self.errlen > err_limit:
- break
- if out_limit and self.outlen > out_limit:
- break
- if timeout:
- if count > timeout:
- break
- count += 1
- if keyword and self.outdata.find(keyword)!=-1:
- break
- app = wx.GetApp()
- if app is not None:
- app.Yield()
- time.sleep(0.01)
+ def endlog(self):
+ if self.endlock.acquire(False):
+ self.finishsem.release()
+ if not self.outt.finished and self.kill_it:
+ self.kill()
- if not self.outt.finished and kill_it:
- self.kill()
+
+ def spin(self):
+ self.finishsem.acquire()
+ return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]
- return [self.exitcode, self.outdata, self.errdata]
-