Fix closing connected RevPiSlaveDev on program exit.

RevPiSlaveDev are daemon threads and we have to .join() after calling .stop()
to let the thread finish its work of disconnect and write default values to
process image.
This commit is contained in:
2020-11-21 10:51:32 +01:00
parent c393b9fb05
commit 1b7c4cddc4
4 changed files with 33 additions and 9 deletions

2
.idea/misc.xml generated
View File

@@ -3,7 +3,7 @@
<component name="JavaScriptSettings"> <component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" /> <option name="languageLevel" value="ES6" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (revpi)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (revpi)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser"> <component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" /> <option name="version" value="3" />
</component> </component>

2
.idea/revpipyload.iml generated
View File

@@ -5,7 +5,7 @@
<sourceFolder url="file://$MODULE_DIR$/revpipyload" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/revpipyload" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.6 (revpi)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.8 (revpi)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

@@ -103,12 +103,21 @@ class RevPiSlave(Thread):
# Socket öffnen und konfigurieren bis Erfolg oder Ende # Socket öffnen und konfigurieren bis Erfolg oder Ende
self.so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.so = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.so.settimeout(2) self.so.settimeout(2)
sock_bind_err = False
while not self._evt_exit.is_set(): while not self._evt_exit.is_set():
try: try:
self.so.bind((self._bindip, self._port)) self.so.bind((self._bindip, self._port))
except Exception as e: if sock_bind_err:
proginit.logger.warning( proginit.logger.warning(
"can not bind socket: {0} - retry".format(e) "successful bind picontrolserver to socket "
"after error"
)
except Exception as e:
if not sock_bind_err:
sock_bind_err = True
proginit.logger.warning(
"can not bind picontrolserver to socket: {0} "
"- retrying".format(e)
) )
self._evt_exit.wait(1) self._evt_exit.wait(1)
else: else:
@@ -149,9 +158,18 @@ class RevPiSlave(Thread):
th_check for th_check in self._th_dev if th_check.is_alive() th_check for th_check in self._th_dev if th_check.is_alive()
] ]
# Alle Threads beenden # Disconnect all clients and wait some time, because they are daemons
for th in self._th_dev: th_close_err = False
for th in self._th_dev: # type: RevPiSlaveDev
th.stop() th.stop()
for th in self._th_dev: # type: RevPiSlaveDev
th.join(2.0)
if th.is_alive():
th_close_err = True
if th_close_err:
proginit.logger.warning(
"piControlServer could not disconnect all clients in timeout"
)
# Socket schließen # Socket schließen
self.so.close() self.so.close()
@@ -600,7 +618,13 @@ class RevPiSlaveDev(Thread):
proginit.logger.debug("leave RevPiSlaveDev.run()") proginit.logger.debug("leave RevPiSlaveDev.run()")
def stop(self): def stop(self):
"""Beendet Verbindungsthread.""" """
Send signal to disconnect from client.
This will be a dirty disconnect and the thread needs some time to close
the connection. Call .join() to give the thread some time, it is a
daemon!
"""
proginit.logger.debug("enter RevPiSlaveDev.stop()") proginit.logger.debug("enter RevPiSlaveDev.stop()")
self._evt_exit.set() self._evt_exit.set()

View File

@@ -27,7 +27,7 @@ setup(
license="LGPLv3", license="LGPLv3",
name="revpipyload", name="revpipyload",
version="0.9.2d", version="0.9.2e",
scripts=[ scripts=[
"data/revpipyload", "data/revpipyload",