fix: ensure all daw_engine exit on app close (abrupt kill + LAN client open)
- desktop_engine: watchdog parent check via WaitForSingleObject(SYNCHRONIZE) instead of OpenProcess — killed parents linger as zombie objects, OpenProcess succeeds forever and watchdog never fires; hard-exit after 5s if graceful shutdown hangs (open LAN connection) - lib.rs: Destroyed handler sweeps any orphan daw_engine/daw_vst_bridge by image name before exit(0), covering manual-launch and stale engines
This commit is contained in:
+23
-3
@@ -61,12 +61,21 @@ def _parent_alive(pid):
|
||||
# pid khong con ton tai.
|
||||
if os.name == "nt":
|
||||
import ctypes
|
||||
# OpenProcess chi bao NULL khi process object da bi reap (moi handle
|
||||
# dong het). Process vua bi kill (taskkill/crash) con "zombie" mot
|
||||
# thoi gian -> OpenProcess van thanh cong -> watchdog tuong cha con
|
||||
# song -> engine khong bao gio tu thoat. WaitForSingleObject tren
|
||||
# handle co PROCESS_SYNCHRONIZE phan biet dung: object da terminate
|
||||
# thi SIGNALED ngay, du handle con ton tai.
|
||||
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
|
||||
h = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pid)
|
||||
PROCESS_SYNCHRONIZE = 0x00100000
|
||||
h = ctypes.windll.kernel32.OpenProcess(
|
||||
PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SYNCHRONIZE, False, pid)
|
||||
if not h:
|
||||
return False # tien trinh da chet
|
||||
return False # process object da mat -> cha da chet
|
||||
terminated = ctypes.windll.kernel32.WaitForSingleObject(h, 0) == 0
|
||||
ctypes.windll.kernel32.CloseHandle(h)
|
||||
return True
|
||||
return not terminated
|
||||
try:
|
||||
os.kill(pid, 0)
|
||||
return True
|
||||
@@ -140,6 +149,17 @@ def main():
|
||||
logging.getLogger("desktop_engine").info(
|
||||
"Parent process exited — shutting down engine")
|
||||
server.should_exit = True
|
||||
# Graceful shutdown co the TREO vo han: uvicorn
|
||||
# _wait_tasks_to_complete cho open connection (client LAN
|
||||
# dang mo browser) va timeout_graceful_shutdown=None.
|
||||
# => engine song dai khi app chet dot ngot (crash/Task
|
||||
# Manager). Hard-exit fallback sau 5s dam bao thoat het.
|
||||
def _force_exit():
|
||||
time.sleep(5.0)
|
||||
logging.getLogger("desktop_engine").info(
|
||||
"Graceful shutdown hung — forcing exit")
|
||||
os._exit(0)
|
||||
threading.Thread(target=_force_exit, daemon=True).start()
|
||||
return
|
||||
threading.Thread(target=_watchdog, daemon=True).start()
|
||||
|
||||
|
||||
Binary file not shown.
@@ -671,6 +671,18 @@ pub fn run() {
|
||||
// phu/an giu event loop song, Tauri khong tu exit; exit(0)
|
||||
// ket thuc dut diem (pump da dung, khong con respawn bridge).
|
||||
if window.label() == "main" {
|
||||
// Orphan sweep: bat CA dau engine con song theo image name —
|
||||
// engine spawn thu cong (khong co SF_PARENT_PID), engine cua
|
||||
// lan chay truoc bi crash, hoac engine song sot khi app chet
|
||||
// dot ngot (watchdog graceful shutdown treo vi LAN client).
|
||||
// Task Manager dong app -> Destroyed khong chay -> engine tu
|
||||
// thoat nho watchdog; o day dong app binh thuong -> quet het.
|
||||
let _ = std::process::Command::new("taskkill")
|
||||
.args(["/IM", "daw_engine.exe", "/T", "/F"])
|
||||
.status();
|
||||
let _ = std::process::Command::new("taskkill")
|
||||
.args(["/IM", "daw_vst_bridge.exe", "/T", "/F"])
|
||||
.status();
|
||||
window.app_handle().exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user