{"record":{"id":"56cdab00ea54fef2","repo":"tokio-rs/tokio","slug":"signal-driver-gone","errorCode":null,"errorMessage":"signal driver gone","messagePattern":"signal driver gone","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"tokio/src/runtime/signal/mod.rs","lineNumber":137,"sourceCode":"                Ok(_) => continue, // Keep reading\n                Err(e) if e.kind() == std_io::ErrorKind::WouldBlock => break,\n                Err(e) => panic!(\"Bad read on self-pipe: {e}\"),\n            }\n        }\n\n        // Broadcast any signals which were received\n        globals().broadcast();\n    }\n}\n\n// ===== impl Handle =====\n\nimpl Handle {\n    pub(crate) fn check_inner(&self) -> std_io::Result<()> {\n        if self.inner.strong_count() > 0 {\n            Ok(())\n        } else {\n            Err(std_io::Error::new(\n                std_io::ErrorKind::Other,\n                \"signal driver gone\",\n            ))\n        }\n    }\n}\n","sourceCodeStart":119,"sourceCodeEnd":144,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio/src/runtime/signal/mod.rs#L119-L144","documentation":"Handle::check_inner for the signal driver returns this io::Error when the inner driver Arc's strong_count is 0, i.e. the signal driver thread/loop has been dropped. Any signal API (signal::ctrl_c, unix::signal) needs the live driver to deliver notifications.","triggerScenarios":"Calling signal::ctrl_c() or Signal::new() when the runtime was built without a signal driver or the runtime/driver has been dropped; using a current-thread runtime that exited.","commonSituations":"Building a runtime with only enable_time() (not enable_all); dropping the runtime then awaiting ctrl_c; calling signal APIs from a non-Tokio thread after the runtime ended.","solutions":["Build the runtime with enable_all() (or enable_io + enable_signal) so the signal driver runs.","Keep the runtime alive across the entire span of signal::ctrl_c().await.","Call signal APIs only from within tokio runtime context.","Treat 'signal driver gone' as terminal shutdown and exit the process gracefully."],"exampleFix":"// before\nlet rt = runtime::Builder::new_current_thread().enable_time().build()?;\nrt.block_on(async { signal::ctrl_c().await }); // fails: no signal driver\n// after\nlet rt = runtime::Builder::new_current_thread().enable_all().build()?;\nrt.block_on(async { signal::ctrl_c().await });","handlingStrategy":"try-catch","validationCode":"// Ensure the runtime was built with enable_all before relying on signals.\n// For manual builds: Builder::new_current_thread().enable_all().build()","typeGuard":null,"tryCatchPattern":"match signal::ctrl_c().await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"signal driver gone\") => {\n        // graceful: treat as shutdown\n        return;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use enable_all() so the signal driver runs.","Keep the runtime alive for the duration of signal::ctrl_c().await.","Call signal APIs only inside tokio runtime context."],"tags":["signal","signal-driver","runtime","shutdown","io-error"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}