fix: zombie IQ process holds USB and stale WS handler clobbers shared state

Two root causes for the waterfall/monitor lockup when scrolling past the
2.4 MHz RTL-SDR span:

1. safe_terminate() sent SIGKILL but never called wait(), leaving a
   zombie process that kept the USB device handle open. The subsequent
   capture restart failed the USB probe and the monitor could not use
   the shared IQ path, falling back to a process-based monitor that
   stole the SDR from the waterfall.

2. When the frontend created a new WebSocket after a failure, the old
   handler's finally block called _set_shared_capture_state(running=False)
   which could race with the new handler's running=True, making the
   shared monitor path unavailable. Added a generation counter so only
   the owning handler can clear the shared state.
This commit is contained in:
Smittix
2026-02-23 21:59:03 +00:00
parent 0daee74cf0
commit 0a4a0689a0
2 changed files with 35 additions and 6 deletions

View File

@@ -76,6 +76,10 @@ def safe_terminate(process: subprocess.Popen | None, timeout: float = 2.0) -> bo
return True
except subprocess.TimeoutExpired:
process.kill()
try:
process.wait(timeout=3)
except subprocess.TimeoutExpired:
pass
unregister_process(process)
return True
except Exception as e: