PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
authorEdouard Tisserant
Sat, 14 Apr 2018 10:09:33 +0200
changeset 1988 19ca02e8074f
parent 1987 8d1aca3c9e83
child 1989 9b5c712f4488
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.
Beremiz_service.py
runtime/PLCObject.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
 
--- 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