Code cleanup, make sure race conditions can't happen, at least in theory.

This commit is contained in:
Storm Dragon 2025-06-20 03:10:07 -04:00
parent f4ed8da4c3
commit 64e79f6945
3 changed files with 36 additions and 24 deletions

View File

@ -45,21 +45,27 @@ class driver(remoteDriver):
continue continue
if self.fenrirSock in r: if self.fenrirSock in r:
client_sock, client_addr = self.fenrirSock.accept() client_sock, client_addr = self.fenrirSock.accept()
try: # Ensure client socket is always closed to prevent resource leaks
rawdata = client_sock.recv(8129) try:
except Exception as e: try:
self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error receiving data from client: ' + str(e), debug.debugLevel.ERROR) rawdata = client_sock.recv(8129)
try: except Exception as e:
data = rawdata.decode("utf-8").rstrip().lstrip() self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error receiving data from client: ' + str(e), debug.debugLevel.ERROR)
eventQueue.put({"Type":fenrirEventType.RemoteIncomming, rawdata = b'' # Set default empty data if recv fails
"Data": data
}) try:
except Exception as e: data = rawdata.decode("utf-8").rstrip().lstrip()
self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error decoding/queuing data: ' + str(e), debug.debugLevel.ERROR) eventQueue.put({"Type":fenrirEventType.RemoteIncomming,
try: "Data": data
client_sock.close() })
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error closing client socket: ' + str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error decoding/queuing data: ' + str(e), debug.debugLevel.ERROR)
finally:
# Always close client socket, even if data processing fails
try:
client_sock.close()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error closing client socket: ' + str(e), debug.debugLevel.ERROR)
if self.fenrirSock: if self.fenrirSock:
self.fenrirSock.close() self.fenrirSock.close()
self.fenrirSock = None self.fenrirSock = None

View File

@ -57,6 +57,9 @@ class driver(soundDriver):
return return
self.cancel() self.cancel()
self.mainloop.quit() self.mainloop.quit()
# Wait for the GLib MainLoop thread to finish to prevent shutdown races
if hasattr(self, 'thread') and self.thread.is_alive():
self.thread.join(timeout=2.0) # 2 second timeout to prevent hanging
def _onPlayerMessage(self, bus, message): def _onPlayerMessage(self, bus, message):
if not self._initialized: if not self._initialized:

View File

@ -73,17 +73,20 @@ class driver(speechDriver):
return return
self.clear_buffer() self.clear_buffer()
self.lock.acquire(True) self.lock.acquire(True)
if self.proc: try:
try: if self.proc:
self.proc.terminate()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)
try: try:
self.proc.kill() self.proc.terminate()
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING) self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)
self.proc = None try:
self.lock.release() self.proc.kill()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING)
self.proc = None
finally:
# Ensure lock is always released, even if process termination fails
self.lock.release()
def setCallback(self, callback): def setCallback(self, callback):
print('SpeechDummyDriver: setCallback') print('SpeechDummyDriver: setCallback')