diff -r 3f3f9dce9140 -r 2b00f90c6888 runtime/PLCObject.py --- a/runtime/PLCObject.py Tue Feb 02 13:47:48 2021 +0100 +++ b/runtime/PLCObject.py Fri Apr 09 09:45:28 2021 +0200 @@ -398,8 +398,10 @@ self.PythonRuntimeCall("init", use_evaluator=False) self.PythonThreadCondLock = Lock() - self.PythonThreadCond = Condition(self.PythonThreadCondLock) - self.PythonThreadCmd = "Wait" + self.PythonThreadCmdCond = Condition(self.PythonThreadCondLock) + self.PythonThreadAckCond = Condition(self.PythonThreadCondLock) + self.PythonThreadCmd = None + self.PythonThreadAck = None self.PythonThread = Thread(target=self.PythonThreadProc, name="PLCPythonThread") self.PythonThread.start() @@ -442,24 +444,43 @@ while True: self.PythonThreadCondLock.acquire() cmd = self.PythonThreadCmd - while cmd == "Wait": - self.PythonThreadCond.wait() + while cmd is None: + self.PythonThreadCmdCond.wait() cmd = self.PythonThreadCmd - self.PythonThreadCmd = "Wait" + self.PythonThreadCmd = None self.PythonThreadCondLock.release() - if cmd == "Activate": + if cmd == "PreStart": + self.PreStartPLC() + # Ack once PreStart done, must be finished before StartPLC + self.PythonThreadAcknowledge(cmd) + elif cmd == "Start": + # Ack Immediately, for responsiveness + self.PythonThreadAcknowledge(cmd) self.PythonRuntimeCall("start") - self.PreStartPLC() + self.LogMessage("Python extensions started") self.PythonThreadLoop() self.PythonRuntimeCall("stop", reverse_order=True) - else: # "Finish" + elif cmd == "Finish": + self.PythonThreadAcknowledge(cmd) break + def PythonThreadAcknowledge(self, ack): + self.PythonThreadCondLock.acquire() + self.PythonThreadAck = ack + self.PythonThreadAckCond.notify() + self.PythonThreadCondLock.release() + def PythonThreadCommand(self, cmd): self.PythonThreadCondLock.acquire() self.PythonThreadCmd = cmd - self.PythonThreadCond.notify() + self.PythonThreadCmdCond.notify() + ack = None + while ack != cmd: + self.PythonThreadAckCond.wait() + ack = self.PythonThreadAck + self.PythonThreadAck = None + self.PythonThreadCondLock.release() def _fail(self, msg): @@ -483,13 +504,14 @@ self._fail(_("Problem starting PLC : can't load PLC")) if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: + self.PythonThreadCommand("PreStart") c_argv = ctypes.c_char_p * len(self.argv) res = self._startPLC(len(self.argv), c_argv(*self.argv)) if res == 0: + self.LogMessage("PLC started") self.PLCStatus = PlcStatus.Started self.StatusChange() - self.PythonThreadCommand("Activate") - self.LogMessage("PLC started") + self.PythonThreadCommand("Start") else: self._fail(_("Problem starting PLC : error %d" % res))