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.
--- 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
+}
+