1 use std::sync::atomic::{AtomicUsize, Ordering};
2 use std::time::Duration;
3
4 // atomic duration in milli seconds
5 #[derive(Debug)]
6 pub struct AtomicDuration(AtomicUsize);
7
8 impl AtomicDuration {
new(dur: Option<Duration>) -> Self9 pub fn new(dur: Option<Duration>) -> Self {
10 let dur = match dur {
11 None => 0,
12 Some(d) => dur_to_ms(d) as usize,
13 };
14
15 AtomicDuration(AtomicUsize::new(dur))
16 }
17
18 #[inline]
get(&self) -> Option<Duration>19 pub fn get(&self) -> Option<Duration> {
20 match self.0.load(Ordering::Relaxed) {
21 0 => None,
22 d => Some(Duration::from_millis(d as u64)),
23 }
24 }
25
26 #[inline]
swap(&self, dur: Option<Duration>) -> Option<Duration>27 pub fn swap(&self, dur: Option<Duration>) -> Option<Duration> {
28 let timeout = match dur {
29 None => 0,
30 Some(d) => dur_to_ms(d) as usize,
31 };
32
33 match self.0.swap(timeout, Ordering::Relaxed) {
34 0 => None,
35 d => Some(Duration::from_millis(d as u64)),
36 }
37 }
38 }
39
dur_to_ms(dur: Duration) -> u6440 fn dur_to_ms(dur: Duration) -> u64 {
41 // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair
42 const MS_PER_SEC: u64 = 1_000;
43 const NANOS_PER_MILLI: u64 = 1_000_000;
44 let ns = u64::from(dur.subsec_nanos());
45 let ms = (ns + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
46 dur.as_secs().saturating_mul(MS_PER_SEC).saturating_add(ms)
47 }
48