use std::sync::{Arc, atomic::{AtomicU8, Ordering}};
#[derive(Debug, Clone, Default)]
pub(crate) struct SteerSignal(Arc<AtomicU8>);
const STEER_IDLE: u8 = 0;
const STEER_ARMED: u8 = 1;
const STEER_FINALIZING: u8 = 2;
impl SteerSignal {
pub fn arm(&self) {
if self.0.load(Ordering::SeqCst) != STEER_FINALIZING {
self.0.store(STEER_ARMED, Ordering::SeqCst);
}
}
pub fn disarm(&self) {
if self.0.load(Ordering::SeqCst) != STEER_FINALIZING {
self.0.store(STEER_IDLE, Ordering::SeqCst);
}
}
pub fn reset(&self) {
self.0.store(STEER_IDLE, Ordering::SeqCst);
}
pub fn is_armed(&self) -> bool {
self.0.load(Ordering::SeqCst) == STEER_ARMED
}
pub fn begin_preempt(&self) -> bool {
self.0
.compare_exchange(
STEER_ARMED,
STEER_FINALIZING,
Ordering::SeqCst,
Ordering::SeqCst,
)
.is_ok()
}
pub fn is_finalizing(&self) -> bool {
self.0.load(Ordering::SeqCst) == STEER_FINALIZING
}
}