diff -r 20eb4e7a0647 -r 8f0d6c5fd55f runtime/PLCObject.py --- a/runtime/PLCObject.py Mon Apr 08 12:53:18 2019 +0200 +++ b/runtime/PLCObject.py Tue Apr 09 09:13:55 2019 +0200 @@ -23,7 +23,7 @@ from __future__ import absolute_import -from threading import Thread, Lock, Semaphore, Event +from threading import Thread, Lock, Event, Condition import ctypes import os import sys @@ -379,17 +379,22 @@ self.LogMessage(0, traceback.format_exc()) raise - self.PythonRuntimeCall("init") + self.PythonThreadCondLock = Lock() + self.PythonThreadCond = Condition(self.PythonThreadCondLock) + self.PythonThreadCmd = "Wait" + self.PythonThread = Thread(target=self.PythonThreadProc) + self.PythonThread.start() + # used internaly def PythonRuntimeCleanup(self): if self.python_runtime_vars is not None: - self.PythonRuntimeCall("cleanup") + self.PythonThreadCommand("Finish") + self.PythonThread.join() self.python_runtime_vars = None - def PythonThreadProc(self): - self.StartSem.release() + def PythonThreadLoop(self): res, cmd, blkid = "None", "None", ctypes.c_void_p() compile_cache = {} while True: @@ -415,6 +420,37 @@ res = "#EXCEPTION : "+str(e) self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e))) + def PythonThreadProc(self): + print('self.PythonRuntimeCall("init")') + self.PythonRuntimeCall("init") + + while True: + self.PythonThreadCondLock.acquire() + cmd = self.PythonThreadCmd + while cmd == "Wait": + self.PythonThreadCond.wait() + cmd = self.PythonThreadCmd + self.PythonThreadCmd = "Wait" + self.PythonThreadCondLock.release() + + if cmd == "Activate" : + print('self.PythonRuntimeCall("start")') + self.PythonRuntimeCall("start") + + self.PythonThreadLoop() + + self.PythonRuntimeCall("stop") + else: # "Finish" + break + + self.PythonRuntimeCall("cleanup") + + def PythonThreadCommand(self, cmd): + self.PythonThreadCondLock.acquire() + self.PythonThreadCmd = cmd + self.PythonThreadCond.notify() + self.PythonThreadCondLock.release() + @RunInMain def StartPLC(self): if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: @@ -423,11 +459,7 @@ if res == 0: self.PLCStatus = PlcStatus.Started self.StatusChange() - self.PythonRuntimeCall("start") - self.StartSem = Semaphore(0) - self.PythonThread = Thread(target=self.PythonThreadProc) - self.PythonThread.start() - self.StartSem.acquire() + self.PythonThreadCommand("Activate") self.LogMessage("PLC started") else: self.LogMessage(0, _("Problem starting PLC : error %d" % res)) @@ -439,10 +471,8 @@ if self.PLCStatus == PlcStatus.Started: self.LogMessage("PLC stopped") self._stopPLC() - self.PythonThread.join() self.PLCStatus = PlcStatus.Stopped self.StatusChange() - self.PythonRuntimeCall("stop") if self.TraceThread is not None: self.TraceThread.join() self.TraceThread = None