use parking_lot::Once;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use crate::traits::AbortSignal;
static INIT: Once = Once::new();
static CTRL_C_PRESSED: AtomicBool = AtomicBool::new(false);
#[derive(Default, Clone)]
pub struct CtrlCAbortSignal;
impl CtrlCAbortSignal {
pub fn new() -> Self {
let signal = Self {};
signal.init_handler();
signal
}
fn init_handler(&self) {
INIT.call_once(|| {
#[allow(clippy::expect_used)]
ctrlc::set_handler(move || {
println!("Ctrl-C pressed");
CTRL_C_PRESSED.store(true, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");
});
}
}
impl AbortSignal for CtrlCAbortSignal {
fn is_aborted(&self) -> bool {
CTRL_C_PRESSED.load(Ordering::SeqCst)
}
fn abort(&self) {
CTRL_C_PRESSED.store(true, Ordering::SeqCst)
}
fn reset(&self) {
CTRL_C_PRESSED.store(false, Ordering::SeqCst);
}
}
#[derive(Default, Clone)]
pub struct AtomicAbortSignal {
abort: Arc<AtomicBool>,
}
impl AtomicAbortSignal {
pub fn new() -> Self {
Self {
abort: Arc::new(AtomicBool::new(false)),
}
}
}
impl AbortSignal for AtomicAbortSignal {
fn is_aborted(&self) -> bool {
self.abort.load(Ordering::SeqCst)
}
fn abort(&self) {
self.abort.store(true, Ordering::SeqCst);
}
fn reset(&self) {
self.abort.store(false, Ordering::SeqCst);
}
}