--- a/Beremiz_service.py Tue Apr 16 14:45:41 2019 +0200
+++ b/Beremiz_service.py Thu Apr 18 14:42:23 2019 +0200
@@ -532,7 +532,8 @@
pyro_thread_started = Lock()
pyro_thread_started.acquire()
pyro_thread = Thread(target=pyroserver.PyroLoop,
- kwargs=dict(when_ready=pyro_thread_started.release))
+ kwargs=dict(when_ready=pyro_thread_started.release),
+ name="PyroThread")
pyro_thread.start()
# Wait for pyro thread to be effective
@@ -557,7 +558,7 @@
else:
ui_thread_target = app.MainLoop
- ui_thread = Thread(target=ui_thread_target)
+ ui_thread = Thread(target=ui_thread_target, name="UIThread")
ui_thread.start()
# This order ui loop to unblock main thread when ready.
@@ -581,6 +582,7 @@
pass
pyroserver.Quit()
+pyro_thread.join()
plcobj = runtime.GetPLCObjectSingleton()
plcobj.StopPLC()
@@ -588,7 +590,9 @@
if havetwisted:
reactor.stop()
+ ui_thread.join()
elif havewx:
app.ExitMainLoop()
+ ui_thread.join()
sys.exit(0)
--- a/ProjectController.py Tue Apr 16 14:45:41 2019 +0200
+++ b/ProjectController.py Thu Apr 18 14:42:23 2019 +0200
@@ -1446,13 +1446,13 @@
def UpdateMethodsFromPLCStatus(self):
updated = False
- status = None
+ status = PlcStatus.Disconnected
if self._connector is not None:
PLCstatus = self._connector.GetPLCstatus()
if PLCstatus is not None:
status, log_count = PLCstatus
self.UpdatePLCLog(log_count)
- if status is None:
+ if status == PlcStatus.Disconnected:
self._SetConnector(None, False)
status = PlcStatus.Disconnected
if self.previous_plcstate != status:
Binary file images/Repair.png has changed
--- a/runtime/PLCObject.py Tue Apr 16 14:45:41 2019 +0200
+++ b/runtime/PLCObject.py Thu Apr 18 14:42:23 2019 +0200
@@ -388,7 +388,7 @@
self.PythonThreadCondLock = Lock()
self.PythonThreadCond = Condition(self.PythonThreadCondLock)
self.PythonThreadCmd = "Wait"
- self.PythonThread = Thread(target=self.PythonThreadProc)
+ self.PythonThread = Thread(target=self.PythonThreadProc, name="PLCPythonThread")
self.PythonThread.start()
# used internaly
@@ -477,8 +477,14 @@
return True
return False
- @RunInMain
def GetPLCstatus(self):
+ try:
+ return self._GetPLCstatus()
+ except EOFError:
+ return (PlcStatus.Disconnected, None)
+
+ @RunInMain
+ def _GetPLCstatus(self):
return self.PLCStatus, map(self.GetLogCount, xrange(LogLevelsCount))
@RunInMain
@@ -645,7 +651,7 @@
def _TracesSwap(self):
self.LastSwapTrace = time()
if self.TraceThread is None and self.PLCStatus == PlcStatus.Started:
- self.TraceThread = Thread(target=self.TraceThreadProc)
+ self.TraceThread = Thread(target=self.TraceThreadProc, name="PLCTrace")
self.TraceThread.start()
self.TraceLock.acquire()
Traces = self.Traces
--- a/runtime/PyroServer.py Tue Apr 16 14:45:41 2019 +0200
+++ b/runtime/PyroServer.py Thu Apr 18 14:42:23 2019 +0200
@@ -12,6 +12,7 @@
from __future__ import absolute_import
from __future__ import print_function
import sys
+import os
import Pyro
import Pyro.core as pyro
@@ -27,6 +28,7 @@
self.ip_addr = ip_addr
self.port = port
self.servicepublisher = None
+ self.piper, self.pipew = None, None
def _to_be_published(self):
return self.servicename is not None and \
@@ -60,8 +62,11 @@
self.daemon.connect(pyro_obj, "PLCObject")
when_ready()
- self.daemon.requestLoop()
- self.daemon.sock.close()
+ self.piper,self.pipew = os.pipe()
+ self.daemon.requestLoop(others=[self.piper], callback=lambda x:None)
+ self.piper, self.pipew = None, None
+ if hasattr(self,'sock'):
+ self.daemon.sock.close()
self.Unpublish()
def Restart(self):
@@ -70,6 +75,9 @@
def Quit(self):
self.continueloop = False
self.daemon.shutdown(True)
+ self.daemon.closedown()
+ if self.pipew is not None:
+ os.write(self.pipew, "goodbye")
def Publish(self):
self.servicepublisher = ServicePublisher("PYRO")
--- a/runtime/Worker.py Tue Apr 16 14:45:41 2019 +0200
+++ b/runtime/Worker.py Thu Apr 18 14:42:23 2019 +0200
@@ -21,8 +21,9 @@
def __init__(self, call, *args, **kwargs):
self.job = (call, args, kwargs)
self.result = None
- self.success = False
+ self.success = None
self.exc_info = None
+ self.enabled = False
def do(self):
"""
@@ -67,9 +68,11 @@
"""
self._threadID = _thread.get_ident()
self.mutex.acquire()
+ self.enabled = True
if args or kwargs:
_job = job(*args, **kwargs)
_job.do()
+ # _job.success can't be None after do()
if not _job.success:
self.reraise(_job)
@@ -99,6 +102,9 @@
else:
# otherwise notify and wait for completion
self.mutex.acquire()
+ if not self.enabled:
+ self.mutex.release()
+ raise EOFError("Worker is disabled")
while self.job is not None:
self.free.wait()
@@ -110,6 +116,9 @@
self.free.notify()
self.mutex.release()
+ if _job.success is None:
+ raise EOFError("Worker job was interrupted")
+
if _job.success:
return _job.result
else:
@@ -122,6 +131,8 @@
# mark queue
self._finish = True
self.mutex.acquire()
+ self.enabled = False
self.job = None
self.todo.notify()
+ self.done.notify()
self.mutex.release()