use std::{
ops::Deref,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
use tokio::sync::Notify;
#[derive(Clone, Default)]
pub struct Interrupt {
flag: Arc<AtomicBool>,
notify: Arc<Notify>,
}
impl Interrupt {
pub fn new() -> Self {
Self::default()
}
pub fn trigger(&self) {
self.flag.store(true, Ordering::SeqCst);
self.notify.notify_waiters();
}
pub fn is_set(&self) -> bool {
self.flag.load(Ordering::SeqCst)
}
pub async fn wait(&self) {
if self.is_set() {
return;
}
self.notify.notified().await;
}
}
pub struct AutoInterrupt(Interrupt);
impl From<Interrupt> for AutoInterrupt {
fn from(interrupt: Interrupt) -> Self {
Self(interrupt)
}
}
impl Drop for AutoInterrupt {
fn drop(&mut self) {
self.0.trigger();
}
}
impl Deref for AutoInterrupt {
type Target = Interrupt;
fn deref(&self) -> &Self::Target {
&self.0
}
}