#![allow(clippy::exit)]
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use tokio_util::sync::CancellationToken;
#[must_use = "drop the JoinHandle to leak the listener; bind to a `_` to tie its lifetime to the caller scope"]
pub fn install_ctrlc(token: CancellationToken) -> tokio::task::JoinHandle<()> {
tokio::spawn(async move {
let armed = Arc::new(AtomicBool::new(false));
loop {
match tokio::signal::ctrl_c().await {
Ok(()) => {
if armed.swap(true, Ordering::SeqCst) {
tracing::warn!("\nforce-exit on second Ctrl-C");
std::process::exit(130);
}
tracing::info!("\ncancelling… (Ctrl-C again to force)");
token.cancel();
}
Err(_) => return,
}
}
})
}