use std::sync::{Arc, Mutex, PoisonError};
use locode_core::CancellationToken;
use crate::output;
pub type CancelSlot = Arc<Mutex<Option<CancellationToken>>>;
pub fn install_sigterm() -> CancelSlot {
let slot: CancelSlot = Arc::new(Mutex::new(None));
let listener_slot = Arc::clone(&slot);
tokio::spawn(async move {
let Ok(mut sigterm) =
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
else {
return; };
while sigterm.recv().await.is_some() {
let guard = listener_slot.lock().unwrap_or_else(PoisonError::into_inner);
if let Some(handle) = guard.as_ref() {
handle.cancel();
} else {
drop(guard);
output::error_line("SIGTERM before the run started; exiting");
std::process::exit(1);
}
}
});
slot
}
pub fn arm(slot: &CancelSlot, handle: CancellationToken) {
*slot.lock().unwrap_or_else(PoisonError::into_inner) = Some(handle);
}