use std::{
path::PathBuf,
sync::{atomic::AtomicBool, Arc},
thread,
};
use anyhow::Context;
use signal_hook::{consts::TERM_SIGNALS, flag, iterator::Signals};
use tracing::{error, info};
pub struct Handler {
sock: Option<PathBuf>,
}
impl Handler {
pub fn new(sock: Option<PathBuf>) -> Self {
Handler { sock }
}
pub fn spawn(self) -> anyhow::Result<()> {
info!("spawning signal handler thread");
let term_now = Arc::new(AtomicBool::new(false));
for sig in TERM_SIGNALS {
flag::register_conditional_shutdown(*sig, 1, Arc::clone(&term_now))?;
flag::register(*sig, Arc::clone(&term_now))?;
}
let mut signals = Signals::new(TERM_SIGNALS).context("creating signal iterator")?;
thread::spawn(move || {
#[allow(clippy::never_loop)]
for signal in &mut signals {
assert!(TERM_SIGNALS.contains(&signal));
info!("term sig handler: cleaning up socket");
if let Some(sock) = self.sock {
if let Err(e) = std::fs::remove_file(sock).context("cleaning up socket") {
error!("error cleaning up socket file: {}", e);
}
}
info!("term sig handler: exiting");
std::process::exit(0);
}
});
Ok(())
}
}