use {
crate::{AtomicEnum, ReprU8},
std::sync::atomic::Ordering::{self, *},
};
#[derive(Debug)]
pub(crate) struct NeedsFlush(AtomicEnum<NeedsFlushVal>);
impl NeedsFlush {
#[inline]
pub(crate) fn mark_dirty(&self) {
let _ = self.0.compare_exchange(
NeedsFlushVal::No,
NeedsFlushVal::Once,
AcqRel,
Relaxed, );
}
#[inline]
pub(crate) fn on_clone(&self) { self.0.store(NeedsFlushVal::Always, Release); }
#[inline]
pub(crate) fn take(&self) -> bool {
match self.0.compare_exchange(NeedsFlushVal::Once, NeedsFlushVal::No, AcqRel, Acquire) {
Ok(..) => true,
Err(NeedsFlushVal::Always) => true,
Err(.. ) => false,
}
}
#[inline]
pub(crate) fn clear(&self) {
let _ = self.0.compare_exchange(NeedsFlushVal::Once, NeedsFlushVal::No, AcqRel, Relaxed);
}
#[inline]
pub(crate) fn get(&self, ordering: Ordering) -> bool {
matches!(self.0.load(ordering), NeedsFlushVal::Once | NeedsFlushVal::Always)
}
#[inline]
pub(crate) fn get_mut(&mut self) -> bool {
matches!(self.0.get_mut(), NeedsFlushVal::Once | NeedsFlushVal::Always)
}
}
impl From<NeedsFlushVal> for NeedsFlush {
#[inline]
fn from(val: NeedsFlushVal) -> Self { Self(AtomicEnum::new(val)) }
}
#[derive(Debug, PartialEq, Eq)]
#[repr(u8)]
pub(crate) enum NeedsFlushVal {
No,
Once,
Always,
}
unsafe impl ReprU8 for NeedsFlushVal {}