Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
authorEdouard Tisserant
Tue, 22 Jan 2013 19:03:25 +1100
changeset 906 de452d65865c
parent 905 eaa1d3a4b52b
child 907 591cb3d96980
Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
ProjectController.py
connectors/PYRO/__init__.py
runtime/PLCObject.py
targets/plc_debug.c
--- a/ProjectController.py	Thu Jan 17 00:22:35 2013 +0100
+++ b/ProjectController.py	Tue Jan 22 19:03:25 2013 +1100
@@ -113,6 +113,7 @@
         self.DebugThread = None
         self.debug_break = False
         self.previous_plcstate = None
+        self.previous_log_count = -1
         # copy ConfNodeMethods so that it can be later customized
         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
 
@@ -1078,11 +1079,9 @@
 
     ############# Real PLC object access #############
     def UpdateMethodsFromPLCStatus(self):
-        # Get PLC state : Running or Stopped
-        # TODO : use explicit status instead of boolean
         status = None
         if self._connector is not None:
-            status = self._connector.GetPLCstatus()
+            status, log_count = self._connector.GetPLCstatus()
         if status is None:
             self._connector = None
             status = "Disconnected"
@@ -1104,6 +1103,9 @@
                 self.ShowMethod(*args)
             self.previous_plcstate = status
             return True
+        if(self.previous_log_count != log_count):
+            self.logger.write("Now log count is %d"%log_count)
+            self.previous_log_count = log_count
         return False
     
     def PullPLCStatusProc(self, event):
@@ -1277,7 +1279,7 @@
         while (not self.debug_break) and (self._connector is not None):
             Trace = self._connector.GetTraceVariables()
             if(Trace):
-                plc_status, debug_tick, debug_vars = Trace
+                plc_status, log_count, debug_tick, debug_vars = Trace
             else:
                 plc_status = None
             debug_getvar_retry += 1
--- a/connectors/PYRO/__init__.py	Thu Jan 17 00:22:35 2013 +0100
+++ b/connectors/PYRO/__init__.py	Tue Jan 22 19:03:25 2013 +1100
@@ -140,11 +140,11 @@
             if self.RemotePLCObjectProxyCopy is None:
                 self.RemotePLCObjectProxyCopy = copy.copy(confnodesroot._connector.GetPyroProxy())
             return self.RemotePLCObjectProxyCopy.GetTraceVariables()
-        GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",None,None))
+        GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",-1,None,None))
 
         def _PyroGetPLCstatus(self):
             return RemotePLCObjectProxy.GetPLCstatus()
-        GetPLCstatus = PyroCatcher(_PyroGetPLCstatus, "Broken")
+        GetPLCstatus = PyroCatcher(_PyroGetPLCstatus, ("Broken",-1))
 
         def _PyroRemoteExec(self, script, **kwargs):
             return RemotePLCObjectProxy.RemoteExec(script, **kwargs)
--- a/runtime/PLCObject.py	Thu Jan 17 00:22:35 2013 +0100
+++ b/runtime/PLCObject.py	Tue Jan 22 19:03:25 2013 +1100
@@ -145,7 +145,10 @@
 
             self._resumeDebug = self.PLClibraryHandle.resumeDebug
             self._resumeDebug.restype = None
-            
+
+            self._GetLogCount = self.PLClibraryHandle.GetLogCount
+            self._GetLogCount.restype = ctypes.c_uint32
+
             return True
         except:
             PLCprint(traceback.format_exc())
@@ -168,6 +171,7 @@
         self._suspendDebug = lambda x:-1
         self._resumeDebug = lambda:None
         self._PythonIterator = lambda:""
+        self._GetLogCount = lambda:-1 
         self.PLClibraryHandle = None
         # Unload library explicitely
         if getattr(self,"_PLClibraryHandle",None) is not None:
@@ -257,28 +261,22 @@
         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
             c_argv = ctypes.c_char_p * len(self.argv)
             error = None
-            if self._LoadNewPLC():
-                if self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
-                    self.StartSem=Semaphore(0)
-                    self.PythonThread = Thread(target=self.PythonThreadProc)
-                    self.PythonThread.start()
-                    self.StartSem.acquire()
-                else:
-                    error = "starting"
+            res = self._startPLC(len(self.argv),c_argv(*self.argv))
+            if res == 0:
+                self.StartSem=Semaphore(0)
+                self.PythonThread = Thread(target=self.PythonThreadProc)
+                self.PythonThread.start()
+                self.StartSem.acquire()
             else:
-                error = "loading"
-            if error is not None:
-                PLCprint("Problem %s PLC"%error)
+                PLCprint(_("Problem starting PLC : error %d" % res))
                 self.PLCStatus = "Broken"
                 self.StatusChange()
-                self._FreePLC()
             
     def StopPLC(self):
         PLCprint("StopPLC")
         if self.PLCStatus == "Started":
             self._stopPLC()
             self.PythonThread.join()
-            self._FreePLC()
             return True
         return False
 
@@ -295,13 +293,17 @@
         return True
 
     def GetPLCstatus(self):
-        return self.PLCStatus
+        return self.PLCStatus, self._GetLogCount()
     
     def NewPLC(self, md5sum, data, extrafiles):
         PLCprint("NewPLC (%s)"%md5sum)
         if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
             NewFileName = md5sum + lib_ext
             extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
+
+            self._FreePLC()
+            self.PLCStatus = "Empty"
+
             try:
                 os.remove(os.path.join(self.workingdir,
                                        self.CurrentPLCFilename))
@@ -331,11 +333,18 @@
                 # Store new PLC filename
                 self.CurrentPLCFilename = NewFileName
             except:
+                self.PLCStatus = "Broken"
+                self.StatusChange()
                 PLCprint(traceback.format_exc())
                 return False
-            if self.PLCStatus == "Empty":
+
+            if self._LoadNewPLC():
                 self.PLCStatus = "Stopped"
-            return True
+            else:
+                self._FreePLC()
+            self.StatusChange()
+
+            return self.PLCStatus == "Stopped"
         return False
 
     def MatchMD5(self, MD5):
@@ -405,10 +414,10 @@
                     self._FreeDebugData()
                 self.PLClibraryLock.release()
             if offset and offset == size.value:
-                return self.PLCStatus, tick.value, res
+                return self.PLCStatus, self._GetLogCount(), tick.value, res
             #elif size.value:
                 #PLCprint("Debug error - wrong buffer unpack ! %d != %d"%(offset, size.value))
-        return self.PLCStatus, None, []
+        return self.PLCStatus, self._GetLogCount(), None, []
 
     def RemoteExec(self, script, **kwargs):
         try:
--- a/targets/plc_debug.c	Thu Jan 17 00:22:35 2013 +0100
+++ b/targets/plc_debug.c	Tue Jan 22 19:03:25 2013 +1100
@@ -302,3 +302,15 @@
     return wait_error;
 }
 
+
+uint32_t LogMessageCount = 0; 
+
+uint32_t GetLogCount(){
+    return LogMessageCount;
+}
+
+int LogMessage(char* Message){
+    LogMessageCount = __sync_add_and_fetch(&LogMessageCount, 1);
+    return 1; // Success
+}
+