# HG changeset patch # User Laurent Bessard # Date 1353015904 -3600 # Node ID 68ac754a5a727f9ee5f117e3e936e74b33bab21e # Parent 781ced3c0aef7ff18d6d586d830d425902b3c895 Fix bug with concurrent access to LastRefreshTimer in LogPseudoFile for Log Console diff -r 781ced3c0aef -r 68ac754a5a72 Beremiz.py --- a/Beremiz.py Tue Nov 13 11:36:04 2012 +0100 +++ b/Beremiz.py Thu Nov 15 22:45:04 2012 +0100 @@ -196,6 +196,7 @@ self.lock = Lock() self.YieldLock = Lock() self.RefreshLock = Lock() + self.TimerAccessLock = Lock() self.stack = [] self.LastRefreshTime = gettime() self.LastRefreshTimer = None @@ -205,21 +206,27 @@ self.stack.append((s,style)) self.lock.release() current_time = gettime() + self.TimerAccessLock.acquire() if self.LastRefreshTimer: self.LastRefreshTimer.cancel() self.LastRefreshTimer=None + self.TimerAccessLock.release() if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False): self._should_write() else: + self.TimerAccessLock.acquire() self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired) self.LastRefreshTimer.start() + self.TimerAccessLock.release() def _timer_expired(self): if self.RefreshLock.acquire(False): self._should_write() else: + self.TimerAccessLock.acquire() self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired) self.LastRefreshTimer.start() + self.TimerAccessLock.release() def _should_write(self): wx.CallAfter(self._write) diff -r 781ced3c0aef -r 68ac754a5a72 tests/python/plc.xml --- a/tests/python/plc.xml Tue Nov 13 11:36:04 2012 +0100 +++ b/tests/python/plc.xml Thu Nov 15 22:45:04 2012 +0100 @@ -8,7 +8,7 @@ productVersion="0.0" creationDateTime="2008-12-14T16:21:19"/> <contentHeader name="Beremiz Python Support Tests" - modificationDateTime="2012-10-23T00:54:38"> + modificationDateTime="2012-11-15T18:38:58"> <coordinateInfo> <pageSize x="1024" y="1024"/> <fbd> @@ -40,6 +40,17 @@ </struct> </baseType> </dataType> + <dataType name="StateMachine"> + <baseType> + <enum> + <values> + <value name="STANDBY"/> + <value name="START"/> + <value name="STOP"/> + </values> + </enum> + </baseType> + </dataType> </dataTypes> <pous> <pou name="main_pytest" pouType="program"> @@ -109,7 +120,55 @@ <SINT/> </type> </variable> + <variable name="Test_BCD"> + <type> + <WORD/> + </type> + <initialValue> + <simpleValue value="342"/> + </initialValue> + </variable> + <variable name="Test_BCD_RESULT"> + <type> + <UINT/> + </type> + </variable> + <variable name="Test_DT"> + <type> + <DT/> + </type> + <initialValue> + <simpleValue value="DT#2012-11-08-12:17:00"/> + </initialValue> + </variable> + <variable name="Test_TOD"> + <type> + <TOD/> + </type> + </variable> + <variable name="Test_Date"> + <type> + <DATE/> + </type> + </variable> + <variable name="Test_String"> + <type> + <string/> + </type> + </variable> + <variable name="Test_Bool"> + <type> + <BOOL/> + </type> + </variable> </localVars> + <externalVars> + <variable name="Global_RS"> + <type> + <derived name="RS"/> + </type> + </variable> + </externalVars> </interface> <body> <FBD> @@ -610,6 +669,313 @@ <![CDATA[Fast clock, at least faster that sleep(1). See what happens when python takes time to answer : PLC continues.]]> </content> </comment> + <outVariable localId="33" height="30" width="130"> + <position x="1060" y="740"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="35" formalParameter="OUT"> + <position x="1060" y="755"/> + <position x="1005" y="755"/> + </connection> + </connectionPointIn> + <expression>Test_BCD_RESULT</expression> + </outVariable> + <inVariable localId="34" height="30" width="75"> + <position x="785" y="740"/> + <connectionPointOut> + <relPosition x="75" y="15"/> + </connectionPointOut> + <expression>Test_BCD</expression> + </inVariable> + <block localId="35" width="105" height="45" typeName="BCD_TO_UINT"> + <position x="900" y="725"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="34"> + <position x="900" y="755"/> + <position x="860" y="755"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="105" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="36" height="30" width="65"> + <position x="790" y="815"/> + <connectionPointOut> + <relPosition x="65" y="15"/> + </connectionPointOut> + <expression>Test_DT</expression> + </inVariable> + <block localId="37" width="255" height="45" typeName="DATE_AND_TIME_TO_TIME_OF_DAY"> + <position x="900" y="800"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="36"> + <position x="900" y="830"/> + <position x="855" y="830"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="255" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="38" width="195" height="45" typeName="DATE_AND_TIME_TO_DATE"> + <position x="900" y="875"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="36"> + <position x="900" y="905"/> + <position x="877" y="905"/> + <position x="877" y="830"/> + <position x="855" y="830"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="195" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <outVariable localId="39" height="30" width="75"> + <position x="1215" y="815"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="37" formalParameter="OUT"> + <position x="1215" y="830"/> + <position x="1155" y="830"/> + </connection> + </connectionPointIn> + <expression>Test_TOD</expression> + </outVariable> + <outVariable localId="40" height="30" width="80"> + <position x="1215" y="890"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="38" formalParameter="OUT"> + <position x="1215" y="905"/> + <position x="1095" y="905"/> + </connection> + </connectionPointIn> + <expression>Test_Date</expression> + </outVariable> + <outVariable localId="42" height="30" width="90"> + <position x="1100" y="985"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="46" formalParameter="OUT"> + <position x="1100" y="1000"/> + <position x="1030" y="1000"/> + </connection> + </connectionPointIn> + <expression>Test_String</expression> + </outVariable> + <outVariable localId="43" height="30" width="80"> + <position x="1100" y="1055"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="44" formalParameter="OUT"> + <position x="1100" y="1070"/> + <position x="1035" y="1070"/> + </connection> + </connectionPointIn> + <expression>Test_Bool</expression> + </outVariable> + <block localId="44" width="135" height="45" typeName="STRING_TO_BOOL"> + <position x="900" y="1040"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="45"> + <position x="900" y="1070"/> + <position x="850" y="1070"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="135" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="45" height="30" width="55"> + <position x="795" y="1055"/> + <connectionPointOut> + <relPosition x="55" y="15"/> + </connectionPointOut> + <expression>'True'</expression> + </inVariable> + <block localId="46" width="130" height="45" typeName="BYTE_TO_STRING"> + <position x="900" y="970"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="47"> + <position x="900" y="1000"/> + <position x="850" y="1000"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="130" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="47" height="30" width="80"> + <position x="770" y="985"/> + <connectionPointOut> + <relPosition x="80" y="15"/> + </connectionPointOut> + <expression>BYTE#145</expression> + </inVariable> + <inVariable localId="50" height="30" width="105"> + <position x="200" y="1085"/> + <connectionPointOut> + <relPosition x="105" y="15"/> + </connectionPointOut> + <expression>Global_RS.Q1</expression> + </inVariable> + <block localId="51" width="70" height="85" typeName="AND"> + <position x="365" y="1065"/> + <inputVariables> + <variable formalParameter="IN1" negated="true"> + <connectionPointIn> + <relPosition x="0" y="35"/> + <connection refLocalId="50"> + <position x="365" y="1100"/> + <position x="305" y="1100"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="70"/> + <connection refLocalId="52"> + <position x="365" y="1135"/> + <position x="305" y="1135"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="70" y="35"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="52" height="30" width="95"> + <position x="210" y="1120"/> + <connectionPointOut> + <relPosition x="95" y="15"/> + </connectionPointOut> + <expression>BOOL#TRUE</expression> + </inVariable> + <outVariable localId="13" height="30" width="105"> + <position x="510" y="1085"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="51" formalParameter="OUT"> + <position x="510" y="1100"/> + <position x="435" y="1100"/> + </connection> + </connectionPointIn> + <expression>Global_RS.S</expression> + </outVariable> + <outVariable localId="20" height="30" width="105"> + <position x="510" y="1200"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="41" formalParameter="OUT"> + <position x="510" y="1215"/> + <position x="435" y="1215"/> + </connection> + </connectionPointIn> + <expression>Global_RS.R1</expression> + </outVariable> + <inVariable localId="24" height="30" width="105"> + <position x="200" y="1200"/> + <connectionPointOut> + <relPosition x="105" y="15"/> + </connectionPointOut> + <expression>Global_RS.Q1</expression> + </inVariable> + <block localId="41" width="70" height="85" typeName="OR"> + <position x="365" y="1180"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="35"/> + <connection refLocalId="24"> + <position x="365" y="1215"/> + <position x="305" y="1215"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="70"/> + <connection refLocalId="48"> + <position x="365" y="1250"/> + <position x="305" y="1250"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="70" y="35"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="48" height="30" width="100"> + <position x="205" y="1235"/> + <connectionPointOut> + <relPosition x="100" y="15"/> + </connectionPointOut> + <expression>BOOL#FALSE</expression> + </inVariable> </FBD> </body> </pou> @@ -668,6 +1034,13 @@ </type> </variable> </localVars> + <externalVars> + <variable name="Global_RS"> + <type> + <derived name="RS"/> + </type> + </variable> + </externalVars> </interface> <body> <ST> @@ -686,6 +1059,7 @@ } }} (* If you do not use __GET_VAR and _SET_VAR macro, expect unexpected *) +Global_RS(); ]]> </ST> </body> @@ -696,9 +1070,16 @@ <configurations> <configuration name="conf_pytest"> <resource name="res_pytest"> - <task name="pytest_task" interval="t#100ms" priority="0"/> + <task name="pytest_task" interval="T#1ms" priority="0"/> <pouInstance name="pytest_instance" typeName="main_pytest"/> </resource> + <globalVars> + <variable name="Global_RS"> + <type> + <derived name="RS"/> + </type> + </variable> + </globalVars> </configuration> </configurations> </instances>