use core::sync::atomic::{AtomicBool, Ordering};
use core::{mem, ptr};
use crate::libc;
static CANCELLED: AtomicBool = AtomicBool::new(false);
static IS_INIT_DONE: AtomicBool = AtomicBool::new(false);
#[derive(Clone, Copy)]
pub struct CancelToken(&'static AtomicBool);
impl CancelToken {
pub fn init() -> Self {
if IS_INIT_DONE
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
{
unsafe { install_sigint_handler() };
}
CancelToken(&CANCELLED)
}
pub fn cancel(&self) {
self.0.store(true, Ordering::SeqCst);
}
pub fn is_cancelled(&self) -> bool {
self.0.load(Ordering::Relaxed)
}
}
extern "C" fn handle_sigint(_: i32) {
CANCELLED.store(true, Ordering::SeqCst);
}
unsafe fn install_sigint_handler() {
const SIGINT: i32 = 2;
unsafe {
let mut sa: libc::sigaction = mem::zeroed();
sa.sa_flags = 0;
sa.sa_sigaction = handle_sigint as *const () as usize; libc::sigemptyset(&mut sa.sa_mask);
libc::sigaction(SIGINT, &sa, ptr::null_mut());
}
}