use std::sync::Arc;
use tokio::sync::Notify;
pub fn install() -> Arc<Notify> {
let shutdown = Arc::new(Notify::new());
let trigger = shutdown.clone();
tokio::spawn(async move {
wait_for_signal().await;
trigger.notify_waiters();
});
shutdown
}
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigint = signal(SignalKind::interrupt()).expect("failed to install SIGINT handler");
let mut sigterm = signal(SignalKind::terminate()).expect("failed to install SIGTERM handler");
let mut sighup = signal(SignalKind::hangup()).expect("failed to install SIGHUP handler");
let mut sigpipe = signal(SignalKind::pipe()).expect("failed to install SIGPIPE handler");
tokio::spawn(async move {
loop {
sighup.recv().await;
eprintln!("(SIGHUP ignored)");
}
});
tokio::spawn(async move {
loop {
sigpipe.recv().await;
}
});
tokio::select! {
_ = sigint.recv() => eprintln!("\nReceived SIGINT, shutting down..."),
_ = sigterm.recv() => eprintln!("Received SIGTERM, shutting down..."),
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
let _ = tokio::signal::ctrl_c().await;
eprintln!("Received Ctrl+C, shutting down...");
}