use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
#[derive(Debug)]
pub struct AtomicDuration(AtomicUsize);
impl AtomicDuration {
pub fn new(dur: Option<Duration>) -> Self {
let dur = match dur {
None => 0,
Some(d) => dur_to_ms(d) as usize,
};
AtomicDuration(AtomicUsize::new(dur))
}
#[inline]
pub fn get(&self) -> Option<Duration> {
match self.0.load(Ordering::Relaxed) {
0 => None,
d => Some(Duration::from_millis(d as u64)),
}
}
#[inline]
pub fn swap(&self, dur: Option<Duration>) -> Option<Duration> {
let timeout = match dur {
None => 0,
Some(d) => dur_to_ms(d) as usize,
};
match self.0.swap(timeout, Ordering::Relaxed) {
0 => None,
d => Some(Duration::from_millis(d as u64)),
}
}
}
fn dur_to_ms(dur: Duration) -> u64 {
const MS_PER_SEC: u64 = 1_000;
const NANOS_PER_MILLI: u64 = 1_000_000;
let ns = u64::from(dur.subsec_nanos());
let ms = (ns + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
dur.as_secs().saturating_mul(MS_PER_SEC).saturating_add(ms)
}