# HG changeset patch # User Edouard Tisserant # Date 1523693373 -7200 # Node ID 19ca02e8074f5cca6761a05decb690ee49131dfc # Parent 8d1aca3c9e8301d2ec9198ddf697cf269acab738 PLCObject got more methods serialized through worker : Start, Stop, NewPLC. This particularly helps with initialization/startup/re-load problems when targeting Xenomai. It should help in general for runtime robustness, since those operations aren't meant to be executed concurrently. diff -r 8d1aca3c9e83 -r 19ca02e8074f Beremiz_service.py --- a/Beremiz_service.py Fri Apr 13 00:29:52 2018 +0200 +++ b/Beremiz_service.py Sat Apr 14 10:09:33 2018 +0200 @@ -411,11 +411,11 @@ self.port = port self.workdir = workdir self.argv = argv - self.plcobj = None self.servicepublisher = None self.statuschange = statuschange self.evaluator = evaluator self.pyruntimevars = pyruntimevars + self.plcobj = PLCObject(self) def _to_be_published(self): return self.servicename is not None and \ @@ -465,9 +465,6 @@ self.plcobj.UnLoadPLC() self._stop() - def RegisterPLCObject(self, plcobj): - self.plcobj = plcobj - def _stop(self): if self.plcobj is not None: self.plcobj.StopPLC() @@ -476,6 +473,14 @@ self.servicepublisher = None self.daemon.shutdown(True) + def AutoLoad(self): + self.plcobj.AutoLoad() + if self.plcobj.GetPLCstatus()[0] == "Stopped": + if autostart: + self.plcobj.StartPLC() + self.plcobj.StatusChange() + + if enabletwisted: import warnings @@ -626,14 +631,6 @@ except Exception: LogMessageAndException(_("WAMP client startup failed. ")) -plcobj = PLCObject(pyroserver) - -plcobj.AutoLoad() -if plcobj.GetPLCstatus()[0] == "Stopped": - if autostart: - plcobj.StartPLC() -plcobj.StatusChange() - pyro_thread = Thread(target=pyroserver.PyroLoop) pyro_thread.start() @@ -653,7 +650,7 @@ ui_thread.start() try: - MainWorker.runloop() + MainWorker.runloop(pyroserver.AutoLoad) except KeyboardInterrupt: pass diff -r 8d1aca3c9e83 -r 19ca02e8074f runtime/PLCObject.py --- a/runtime/PLCObject.py Fri Apr 13 00:29:52 2018 +0200 +++ b/runtime/PLCObject.py Sat Apr 14 10:09:33 2018 +0200 @@ -97,11 +97,14 @@ self.done = Condition(self.mutex) self.job = None - def runloop(self): + def runloop(self,*args,**kwargs): """ meant to be called by worker thread (blocking) """ self._threadID = thread.get_ident() + if args or kwargs: + job(*args,**kwargs).do() + # result is ignored self.mutex.acquire() while not self._finish: self.todo.wait() @@ -186,7 +189,6 @@ self.TraceLock = Lock() self.TraceWakeup = Event() self.Traces = [] - server.RegisterPLCObject(self) def AutoLoad(self): # Get the last transfered PLC if connector must be restart @@ -273,6 +275,7 @@ self._stopPLC_real.restype = None self._PythonIterator = getattr(self.PLClibraryHandle, "PythonIterator", None) + print(self._PythonIterator) if self._PythonIterator is not None: self._PythonIterator.restype = ctypes.c_char_p self._PythonIterator.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)] @@ -480,6 +483,7 @@ res = "#EXCEPTION : "+str(e) self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e))) + @RunInMain def StartPLC(self): if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": c_argv = ctypes.c_char_p * len(self.argv) @@ -498,6 +502,7 @@ self.PLCStatus = "Broken" self.StatusChange() + @RunInMain def StopPLC(self): if self.PLCStatus == "Started": self.LogMessage("PLC stopped") @@ -516,6 +521,7 @@ def GetPLCstatus(self): return self.PLCStatus, map(self.GetLogCount, xrange(LogLevelsCount)) + @RunInMain def NewPLC(self, md5sum, data, extrafiles): if self.PLCStatus in ["Stopped", "Empty", "Broken"]: NewFileName = md5sum + lib_ext