use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, }; pub type AbortSignal = Arc; pub struct AbortSignalInner { ctrlc: AtomicBool, ctrld: AtomicBool, } pub fn create_abort_signal() -> AbortSignal { AbortSignalInner::new() } impl AbortSignalInner { pub fn new() -> AbortSignal { Arc::new(Self { ctrlc: AtomicBool::new(false), ctrld: AtomicBool::new(false), }) } pub fn aborted(&self) -> bool { if self.aborted_ctrlc() { return true; } if self.aborted_ctrld() { return true; } false } pub fn aborted_ctrlc(&self) -> bool { self.ctrlc.load(Ordering::SeqCst) } pub fn aborted_ctrld(&self) -> bool { self.ctrld.load(Ordering::SeqCst) } pub fn reset(&self) { self.ctrlc.store(false, Ordering::SeqCst); self.ctrld.store(false, Ordering::SeqCst); } pub fn set_ctrlc(&self) { self.ctrlc.store(true, Ordering::SeqCst); } pub fn set_ctrld(&self) { self.ctrld.store(true, Ordering::SeqCst); } } pub async fn watch_abort_signal(abort_signal: AbortSignal) { loop { if abort_signal.aborted() { break; } tokio::time::sleep(std::time::Duration::from_millis(100)).await; } }