154 |
154 |
155 self._stopPLC = self._stopPLC_real |
155 self._stopPLC = self._stopPLC_real |
156 else: |
156 else: |
157 # If python confnode is not enabled, we reuse _PythonIterator |
157 # If python confnode is not enabled, we reuse _PythonIterator |
158 # as a call that block pythonthread until StopPLC |
158 # as a call that block pythonthread until StopPLC |
159 self.PythonIteratorLock = Lock() |
159 self.PlcStopping = Event() |
160 self.PythonIteratorLock.acquire() |
|
161 def PythonIterator(res, blkid): |
160 def PythonIterator(res, blkid): |
162 self.PythonIteratorLock.acquire() |
161 self.PlcStopping.clear() |
163 self.PythonIteratorLock.release() |
162 self.PlcStopping.wait() |
164 return None |
163 return None |
165 self._PythonIterator = PythonIterator |
164 self._PythonIterator = PythonIterator |
166 |
165 |
167 def __StopPLC(): |
166 def __StopPLC(): |
168 self._stopPLC_real() |
167 self._stopPLC_real() |
169 self.PythonIteratorLock.release() |
168 self.PlcStopping.set() |
170 self._stopPLC = __StopPLC |
169 self._stopPLC = __StopPLC |
171 |
170 |
172 |
171 |
173 self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables |
172 self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables |
174 self._ResetDebugVariables.restype = None |
173 self._ResetDebugVariables.restype = None |
309 self.PythonRuntimeCall("cleanup") |
308 self.PythonRuntimeCall("cleanup") |
310 |
309 |
311 self.python_runtime_vars = None |
310 self.python_runtime_vars = None |
312 |
311 |
313 def PythonThreadProc(self): |
312 def PythonThreadProc(self): |
314 self.PLCStatus = "Started" |
|
315 self.StatusChange() |
|
316 self.StartSem.release() |
313 self.StartSem.release() |
317 self.PythonRuntimeCall("start") |
|
318 res,cmd,blkid = "None","None",ctypes.c_void_p() |
314 res,cmd,blkid = "None","None",ctypes.c_void_p() |
319 compile_cache={} |
315 compile_cache={} |
320 while True: |
316 while True: |
321 # print "_PythonIterator(", res, ")", |
317 # print "_PythonIterator(", res, ")", |
322 cmd = self._PythonIterator(res,blkid) |
318 cmd = self._PythonIterator(res,blkid) |
339 res=str(result) |
335 res=str(result) |
340 self.python_runtime_vars["FBID"]=None |
336 self.python_runtime_vars["FBID"]=None |
341 except Exception,e: |
337 except Exception,e: |
342 res = "#EXCEPTION : "+str(e) |
338 res = "#EXCEPTION : "+str(e) |
343 self.LogMessage(1,('PyEval@0x%x(Code="%s") Exception "%s"')%(FBID,cmd,str(e))) |
339 self.LogMessage(1,('PyEval@0x%x(Code="%s") Exception "%s"')%(FBID,cmd,str(e))) |
344 self.PLCStatus = "Stopped" |
|
345 self.StatusChange() |
|
346 self.PythonRuntimeCall("stop") |
|
347 |
340 |
348 def StartPLC(self): |
341 def StartPLC(self): |
349 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
342 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
350 c_argv = ctypes.c_char_p * len(self.argv) |
343 c_argv = ctypes.c_char_p * len(self.argv) |
351 error = None |
344 error = None |
352 res = self._startPLC(len(self.argv),c_argv(*self.argv)) |
345 res = self._startPLC(len(self.argv),c_argv(*self.argv)) |
353 if res == 0: |
346 if res == 0: |
|
347 self.PLCStatus = "Started" |
|
348 self.StatusChange() |
|
349 self.PythonRuntimeCall("start") |
354 self.StartSem=Semaphore(0) |
350 self.StartSem=Semaphore(0) |
355 self.PythonThread = Thread(target=self.PythonThreadProc) |
351 self.PythonThread = Thread(target=self.PythonThreadProc) |
356 self.PythonThread.start() |
352 self.PythonThread.start() |
357 self.StartSem.acquire() |
353 self.StartSem.acquire() |
358 self.LogMessage("PLC started") |
354 self.LogMessage("PLC started") |
364 def StopPLC(self): |
360 def StopPLC(self): |
365 if self.PLCStatus == "Started": |
361 if self.PLCStatus == "Started": |
366 self.LogMessage("PLC stopped") |
362 self.LogMessage("PLC stopped") |
367 self._stopPLC() |
363 self._stopPLC() |
368 self.PythonThread.join() |
364 self.PythonThread.join() |
|
365 self.PLCStatus = "Stopped" |
|
366 self.StatusChange() |
|
367 self.PythonRuntimeCall("stop") |
369 if self.TraceThread is not None : |
368 if self.TraceThread is not None : |
370 self.TraceWakeup.set() |
369 self.TraceWakeup.set() |
371 self.TraceThread.join() |
370 self.TraceThread.join() |
372 self.TraceThread = None |
371 self.TraceThread = None |
373 return True |
372 return True |