Fix bug with concurrent access to LastRefreshTimer in LogPseudoFile for Log Console
authorLaurent Bessard
Thu, 15 Nov 2012 22:45:04 +0100
changeset 881 68ac754a5a72
parent 880 781ced3c0aef
child 882 3c6ce0a5ab2c
Fix bug with concurrent access to LastRefreshTimer in LogPseudoFile for Log Console
Beremiz.py
tests/python/plc.xml
--- 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)
--- 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>