Final batch of code stability updates before anouther bout of extended testing. Still plenty to go, but making progress.

This commit is contained in:
Storm Dragon 2025-06-20 03:34:50 -04:00
parent 64e79f6945
commit dda84b9905
7 changed files with 48 additions and 15 deletions

View File

@ -4,7 +4,12 @@
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.commands.vmenu_navigation.vmenu_search_base import VMenuSearchCommand
import importlib.util
import os
_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py"))
_module = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_module)
VMenuSearchCommand = _module.VMenuSearchCommand
class command(VMenuSearchCommand):
def __init__(self):

View File

@ -84,11 +84,9 @@ class commandManager():
fileName = fileName.split('/')[-1]
if fileName.startswith('__'):
continue
try:
if self.env['commands'][section][fileName.upper()] != None:
# Check if command already exists to prevent duplicate loading
if fileName.upper() in self.env['commands'][section] and self.env['commands'][section][fileName.upper()] is not None:
continue
except Exception as e:
pass
if fileExtension.lower() == '.py':
command_mod = module_utils.importModule(fileName, command)
self.env['commands'][section][fileName.upper()] = command_mod.command()

View File

@ -15,7 +15,7 @@ from ctypes import c_bool
class eventManager():
def __init__(self):
self.running = Value(c_bool, True)
self._eventQueue = Queue() # multiprocessing.Queue()
self._eventQueue = Queue(maxsize=100) # Bounded queue to prevent memory exhaustion
self.cleanEventQueue()
def initialize(self, environment):
self.env = environment
@ -85,8 +85,16 @@ class eventManager():
return False
if event == fenrirEventType.Ignore:
return False
if self.getEventQueueSize() > 50:
if not event in [fenrirEventType.ScreenUpdate, fenrirEventType.HeartBeat]:
self.cleanEventQueue()
self._eventQueue.put({"Type":event,"Data":data})
# Use bounded queue - if full, this will block briefly or drop older events
try:
self._eventQueue.put({"Type":event,"Data":data}, timeout=0.1)
except Exception as e:
# Queue full - drop oldest event and add new one for critical events
if event in [fenrirEventType.ScreenUpdate, fenrirEventType.KeyboardInput]:
try:
self._eventQueue.get_nowait() # Remove oldest
self._eventQueue.put({"Type":event,"Data":data}, timeout=0.1)
except:
pass # If still can't add, drop the event
# For non-critical events, just drop them if queue is full
return True

View File

@ -30,11 +30,12 @@ class memoryManager():
if not self.listStorageValid(name):
return
if self.listStorage[name]['maxLength'] == None:
self.listStorage[name]['list'] = [value] + self.listStorage[name]['list']
# Fallback: if maxLength is still None, apply default limit of 1000
self.listStorage[name]['list'] = [value] + self.listStorage[name]['list'][:999]
else:
self.listStorage[name]['list'] = [value] + self.listStorage[name]['list'][:self.listStorage[name]['maxLength'] -1]
self.listStorage[name]['index'] = 0
def addIndexList(self, name, maxLength = None, currList = [], currIndex = -1):
def addIndexList(self, name, maxLength = 1000, currList = [], currIndex = -1):
if len(currList) != 0 and (currIndex == -1):
currIndex = 0
self.listStorage[name] = {'list': currList, 'index': currIndex, 'maxLength': maxLength}

View File

@ -29,9 +29,9 @@ class processManager():
# pass
#except:
# pass
proc.join()
proc.join(timeout=5.0) # Timeout to prevent hanging shutdown
for t in self._Threads:
t.join()
t.join(timeout=5.0) # Timeout to prevent hanging shutdown
def heartBeatTimer(self, active):
try:
time.sleep(0.5)

View File

@ -62,6 +62,18 @@ class driver(soundDriver):
return
if self.soundType == 'file':
self.proc.kill()
try:
self.proc.wait(timeout=1.0) # Wait for process to finish to prevent zombies
except subprocess.TimeoutExpired:
pass # Process already terminated
except Exception as e:
pass # Handle any other wait errors
if self.soundType == 'frequence':
self.proc.kill()
try:
self.proc.wait(timeout=1.0) # Wait for process to finish to prevent zombies
except subprocess.TimeoutExpired:
pass # Process already terminated
except Exception as e:
pass # Handle any other wait errors
self.soundType = ''

View File

@ -10,6 +10,7 @@ from threading import Thread, Lock
from queue import Queue, Empty
import shlex
from subprocess import Popen
import subprocess
from fenrirscreenreader.core.speechDriver import speechDriver
class speakQueue(Queue):
@ -77,10 +78,18 @@ class driver(speechDriver):
if self.proc:
try:
self.proc.terminate()
# Wait for process to finish to prevent zombies
try:
self.proc.wait(timeout=1.0)
except subprocess.TimeoutExpired:
# If terminate didn't work, force kill
self.proc.kill()
self.proc.wait(timeout=1.0)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)
try:
self.proc.kill()
self.proc.wait(timeout=1.0) # Wait after kill to prevent zombies
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING)
self.proc = None