use std::{
sync::{Condvar, Mutex},
time::Duration,
};
pub(crate) struct CancellationToken {
mutex: Mutex<bool>,
cvar: Condvar,
}
impl Default for CancellationToken {
fn default() -> Self {
Self {
mutex: Mutex::new(false),
cvar: Condvar::new(),
}
}
}
impl CancellationToken {
pub fn cancel(&self) {
let mut guard = self
.mutex
.lock()
.expect("cancellation token lock should not be poisoned");
if !*guard {
*guard = true;
self.cvar.notify_all();
}
}
pub fn try_check(&self) -> Option<bool> {
self.mutex.try_lock().ok().map(|guard| *guard)
}
pub fn sleep_with_cancellation(&self, duration: Duration) -> bool {
let guard = self
.mutex
.lock()
.expect("cancellation token lock should not be poisoned");
let (result, _) = self
.cvar
.wait_timeout(guard, duration)
.expect("cancellation token lock should not be poisoned");
*result
}
}