# HG changeset patch # User Edouard Tisserant # Date 1358841805 -39600 # Node ID de452d65865c99ff47272a27fd6a214eb328664a # Parent eaa1d3a4b52b1739a9dc8a14bf1ecc3ee04d5a08 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. diff -r eaa1d3a4b52b -r de452d65865c ProjectController.py --- 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 diff -r eaa1d3a4b52b -r de452d65865c connectors/PYRO/__init__.py --- 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) diff -r eaa1d3a4b52b -r de452d65865c runtime/PLCObject.py --- 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: diff -r eaa1d3a4b52b -r de452d65865c targets/plc_debug.c --- 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 +} +