From 3d18a4bd66a90fb1f4cc60efddb9ff36c84118e7 Mon Sep 17 00:00:00 2001 From: Zachery Aaron Shores-Chmielewski Date: Thu, 23 Jul 2026 16:31:26 +0400 Subject: [PATCH] fix: mvp-chat cleanup leak Stop the mvp-chat process on Ctrl-C/SIGTERM so it tears down cleanly instead of leaking past signal delivery. - orchestrator_app: spawn_stop_listener now spawns a Linux SIGINT/SIGTERM handler (signal_hook) that sends the shutdown signal alongside the existing stdin "stop"/"shutdown"/"quit" listener; on non-Linux the spare sender is dropped. - orchestrator_app: split the channel sender into a stdin_tx clone so the stdin thread and the signal thread each own a sender without moving it out of scope. Signed-off-by: Zachery Aaron Shores-Chmielewski --- crates/mvp-system/src/orchestrator_app.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/mvp-system/src/orchestrator_app.rs b/crates/mvp-system/src/orchestrator_app.rs index 56efd98..25accd1 100644 --- a/crates/mvp-system/src/orchestrator_app.rs +++ b/crates/mvp-system/src/orchestrator_app.rs @@ -4660,6 +4660,7 @@ fn stop_requested(stop_rx: &mpsc::Receiver<()>) -> bool { fn spawn_stop_listener() -> mpsc::Receiver<()> { let (tx, rx) = mpsc::channel(); + let stdin_tx = tx.clone(); thread::spawn(move || { let stdin = std::io::stdin(); for line in stdin.lock().lines().map_while(Result::ok) { @@ -4668,11 +4669,29 @@ fn spawn_stop_listener() -> mpsc::Receiver<()> { || trimmed.eq_ignore_ascii_case("shutdown") || trimmed.eq_ignore_ascii_case("quit") { - let _ = tx.send(()); + let _ = stdin_tx.send(()); break; } } }); + #[cfg(target_os = "linux")] + { + thread::spawn(move || { + let Ok(mut signals) = signal_hook::iterator::Signals::new([ + signal_hook::consts::signal::SIGINT, + signal_hook::consts::signal::SIGTERM, + ]) else { + return; + }; + if signals.forever().next().is_some() { + let _ = tx.send(()); + } + }); + } + #[cfg(not(target_os = "linux"))] + { + drop(tx); + } rx }