use std::sync::atomic::{AtomicBool, Ordering};
pub struct WakeSignal {
signaled: AtomicBool,
}
impl WakeSignal {
pub fn new() -> Self {
Self {
signaled: AtomicBool::new(false),
}
}
pub fn notify(&self) {
self.signaled.store(true, Ordering::Release);
}
pub fn take(&self) -> bool {
self.signaled.swap(false, Ordering::Acquire)
}
pub fn is_signaled(&self) -> bool {
self.signaled.load(Ordering::Acquire)
}
}
impl Default for WakeSignal {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn signal_notify_and_take() {
let signal = WakeSignal::new();
assert!(!signal.is_signaled());
assert!(!signal.take());
signal.notify();
assert!(signal.is_signaled());
assert!(signal.take());
assert!(!signal.is_signaled());
assert!(!signal.take());
}
#[test]
fn multiple_notifies_coalesce() {
let signal = WakeSignal::new();
signal.notify();
signal.notify();
signal.notify();
assert!(signal.take());
assert!(!signal.take());
}
}