{"record":{"id":"be1ed5255debaa9e","repo":"jlcodes99/cockpit-tools","slug":"interrupted","errorCode":"Interrupted","errorMessage":"系统正在关闭，已取消启动 {}","messagePattern":"系统正在关闭，已取消启动 (.+?)","errorType":"error_code","errorClass":"std::io::Error","httpStatus":null,"severity":"warning","filePath":"src-tauri/src/modules/app_lifecycle.rs","lineNumber":36,"sourceCode":"pub fn is_shutdown_started() -> bool {\n    SHUTDOWN_STARTED.load(Ordering::SeqCst)\n}\n\npub fn begin_shutdown() -> bool {\n    let _spawn_guard = lock_process_spawn();\n    !SHUTDOWN_STARTED.swap(true, Ordering::SeqCst)\n}\n\n#[cfg(target_os = \"windows\")]\nfn cancel_system_shutdown() {\n    let _spawn_guard = lock_process_spawn();\n    SHUTDOWN_STARTED.store(false, Ordering::SeqCst);\n}\n\npub fn acquire_process_spawn_guard(program: &str) -> std::io::Result<ProcessSpawnGuard> {\n    let guard = lock_process_spawn();\n    if !process_spawn_allowed(is_shutdown_started()) {\n        return Err(Error::new(\n            ErrorKind::Interrupted,\n            format!(\"系统正在关闭，已取消启动 {}\", program),\n        ));\n    }\n    Ok(ProcessSpawnGuard { _guard: guard })\n}\n\n#[cfg(target_os = \"windows\")]\npub fn install_system_shutdown_listener() -> Result<(), String> {\n    use std::sync::mpsc::sync_channel;\n\n    let (shutdown_tx, shutdown_rx) = sync_channel::<()>(1);\n    std::thread::Builder::new()\n        .name(\"cockpit-system-shutdown-cleanup\".to_string())\n        .spawn(move || {\n            if shutdown_rx.recv().is_ok() {\n                crate::modules::logger::log_info(\n                    \"[Lifecycle] Windows 正在关闭，停止后台注入并禁止创建新子进程\",","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src-tauri/src/modules/app_lifecycle.rs#L18-L54","documentation":"acquire_process_spawn_guard serializes process spawning across the app and refuses to hand out a spawn guard once application shutdown has begun (a shutdown flag checked via process_spawn_allowed/is_shutdown_started). It returns an io::Error of kind Interrupted carrying the cancelled program name. This prevents child processes from being launched while the app is tearing down.","triggerScenarios":"Calling acquire_process_spawn_guard (directly or via any code path that launches a child process) after SHUTDOWN_STARTED has been set — e.g. a background task or async job still trying to spawn PowerShell/other programs while the Tauri app is exiting.","commonSituations":"Background workers, timers, or queued tasks that outlive the shutdown signal and race with app close; long-running operations initiated just before the user quits the application.","solutions":["Treat this error as an expected cancellation: stop the operation and do not retry while shutdown is in progress.","Check the shutdown-started flag before initiating any process launch, and subscribe to the shutdown signal to cancel pending launches.","If the spawn must complete, restructure so the launch happens before shutdown begins, or persist the work and resume on next startup.","If this occurs during normal operation (not shutdown), verify no code path incorrectly sets the shutdown flag early."],"exampleFix":"// before\nlet guard = acquire_process_spawn_guard(\"powershell\")?;\nrun_probe(guard);\n\n// after\nif is_shutdown_started() {\n    return Ok(()); // skip probe during shutdown\n}\nlet guard = match acquire_process_spawn_guard(\"powershell\") {\n    Ok(g) => g,\n    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => return Ok(()),\n    Err(e) => return Err(e),\n};\nrun_probe(guard);","handlingStrategy":"fallback","validationCode":"if is_shutdown_started() {\n    // skip launching; app is shutting down\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match acquire_process_spawn_guard(\"prog\") {\n    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => Ok(()), // cancelled by shutdown\n    other => other,\n}","preventionTips":["Check the shutdown flag before queueing any process launch","Use a cancellation token shared with the shutdown signal for background tasks","Persist pending work and resume after restart instead of spawning during teardown","Treat ErrorKind::Interrupted from spawn guards as expected, not fatal"],"tags":["process-spawn","shutdown","io-error","rust"],"backgroundTag":"operation-cancelled-during-shutdown","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}