Fix bug in Debug refresh lock that, with too much data to debug, flooded GUI and blocked it
--- a/Beremiz.py Wed Oct 31 12:05:44 2012 +0100
+++ b/Beremiz.py Sat Nov 03 17:00:26 2012 +0100
@@ -211,9 +211,16 @@
if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False):
self._should_write()
else:
- self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._should_write)
+ self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired)
self.LastRefreshTimer.start()
+ def _timer_expired(self):
+ if self.RefreshLock.acquire(False):
+ self._should_write()
+ else:
+ self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired)
+ self.LastRefreshTimer.start()
+
def _should_write(self):
wx.CallAfter(self._write)
if MainThread == currentThread().ident:
@@ -225,7 +232,7 @@
def _write(self):
if self.output :
- self.output.Freeze();
+ self.output.Freeze()
self.lock.acquire()
for s, style in self.stack:
if style is None : style=self.black_white
@@ -247,7 +254,7 @@
if newtime - self.rising_timer > 1:
self.risecall()
self.rising_timer = newtime
-
+
def write_warning(self, s):
self.write(s,self.red_white)
--- a/graphics/GraphicCommons.py Wed Oct 31 12:05:44 2012 +0100
+++ b/graphics/GraphicCommons.py Sat Nov 03 17:00:26 2012 +0100
@@ -27,7 +27,7 @@
from math import *
from types import *
import datetime
-from threading import Semaphore
+from threading import Lock,Timer
#-------------------------------------------------------------------------------
# Common constants
@@ -293,6 +293,7 @@
#-------------------------------------------------------------------------------
REFRESH_PERIOD = 0.1
+DEBUG_REFRESH_LOCK = Lock()
class DebugViewer:
@@ -305,10 +306,10 @@
self.DataConsumers = {}
self.LastRefreshTime = gettime()
- self.RefreshLock = Semaphore()
+ self.HasAcquiredLock = False
+ self.AccessLock = Lock()
- self.RefreshTimer = wx.Timer(self, -1)
- self.Bind(wx.EVT_TIMER, self.OnRefreshTimer, self.RefreshTimer)
+ self.LastRefreshTimer = None
self.SetDataProducer(producer)
@@ -366,15 +367,26 @@
self.DataProducer.UnsubscribeDebugIECVariable(iec_path, consumer)
self.DataConsumers = {}
- def OnRefreshTimer(self, event):
- self.RefreshNewData()
- event.Skip()
+ def ShouldRefresh(self):
+ if DEBUG_REFRESH_LOCK.acquire(False):
+ self.AccessLock.acquire()
+ self.HasAcquiredLock = True
+ self.AccessLock.release()
+ self.RefreshNewData()
+ else:
+ self.LastRefreshTimer = Timer(REFRESH_PERIOD, self.ShouldRefresh)
+ self.LastRefreshTimer.start()
def NewDataAvailable(self, *args, **kwargs):
- self.RefreshTimer.Stop()
+ if self.LastRefreshTimer is not None:
+ self.LastRefreshTimer.cancel()
+ self.LastRefreshTimer=None
if not self.Inhibited:
current_time = gettime()
- if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False):
+ if current_time - self.LastRefreshTime > REFRESH_PERIOD and DEBUG_REFRESH_LOCK.acquire(False):
+ self.AccessLock.acquire()
+ self.HasAcquiredLock = True
+ self.AccessLock.release()
self.LastRefreshTime = gettime()
self.Inhibit(True)
wx.CallAfter(self.RefreshViewOnNewData, *args, **kwargs)
@@ -382,12 +394,17 @@
def RefreshViewOnNewData(self, *args, **kwargs):
if self:
self.RefreshNewData(*args, **kwargs)
- self.RefreshTimer.Start(int(REFRESH_PERIOD * 1000), oneShot=True)
+ self.LastRefreshTimer = Timer(REFRESH_PERIOD, self.ShouldRefresh)
+ self.LastRefreshTimer.start()
def RefreshNewData(self, *args, **kwargs):
self.Inhibit(False)
- self.RefreshLock.release()
-
+ self.AccessLock.acquire()
+ if self.HasAcquiredLock:
+ DEBUG_REFRESH_LOCK.release()
+ self.HasAcquiredLock = False
+ self.AccessLock.release()
+
#-------------------------------------------------------------------------------
# Viewer Rubberband
#-------------------------------------------------------------------------------