rat_salsa/timer/
mod.rs

1//!
2//! Support for timers.
3//!
4use crate::event::TimerEvent;
5use std::cell::{Cell, RefCell};
6use std::time::{Duration, Instant};
7
8/// Holds all the timers.
9#[derive(Debug, Default)]
10pub(crate) struct Timers {
11    tags: Cell<usize>,
12    timers: RefCell<Vec<TimerImpl>>,
13}
14
15/// Handle for a submitted timer.
16#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
17pub struct TimerHandle(usize);
18
19#[derive(Debug)]
20struct TimerImpl {
21    tag: usize,
22    count: usize,
23    repeat: Option<usize>,
24    next: Instant,
25    timer: Duration,
26}
27
28impl Timers {
29    /// Returns the next sleep time.
30    pub(crate) fn sleep_time(&self) -> Option<Duration> {
31        let timers = self.timers.borrow();
32        if let Some(timer) = timers.last() {
33            let now = Instant::now();
34            if now > timer.next {
35                Some(Duration::from_nanos(0))
36            } else {
37                Some(timer.next.duration_since(now))
38            }
39        } else {
40            None
41        }
42    }
43
44    /// Polls for the next timer event.
45    pub(crate) fn poll(&self) -> bool {
46        let timers = self.timers.borrow();
47        if let Some(timer) = timers.last() {
48            Instant::now() >= timer.next
49        } else {
50            false
51        }
52    }
53
54    /// Polls for the next timer event.
55    /// Removes/recalculates the event and reorders the queue.
56    pub(crate) fn read(&self) -> Option<TimerEvent> {
57        let mut timers = self.timers.borrow_mut();
58
59        let timer = timers.pop();
60        if let Some(mut timer) = timer {
61            if Instant::now() >= timer.next {
62                let evt = TimerEvent(TimeOut {
63                    handle: TimerHandle(timer.tag),
64                    counter: timer.count,
65                });
66
67                // reschedule
68                if let Some(repeat) = timer.repeat {
69                    timer.count += 1;
70                    if timer.count < repeat {
71                        timer.next += timer.timer;
72                        Self::add_impl(timers.as_mut(), timer);
73                    }
74                }
75
76                Some(evt)
77            } else {
78                timers.push(timer);
79                None
80            }
81        } else {
82            None
83        }
84    }
85
86    fn add_impl(timers: &mut Vec<TimerImpl>, t: TimerImpl) {
87        'f: {
88            for i in 0..timers.len() {
89                if timers[i].next <= t.next {
90                    timers.insert(i, t);
91                    break 'f;
92                }
93            }
94            timers.push(t);
95        }
96    }
97
98    /// Add a timer.
99    #[must_use]
100    pub(crate) fn add(&self, t: TimerDef) -> TimerHandle {
101        let tag = self.tags.get() + 1;
102        self.tags.set(tag);
103
104        let t = TimerImpl {
105            tag,
106            count: 0,
107            repeat: t.repeat,
108            next: if let Some(next) = t.next {
109                next
110            } else {
111                Instant::now() + t.timer
112            },
113            timer: t.timer,
114        };
115
116        let mut timers = self.timers.borrow_mut();
117        Self::add_impl(timers.as_mut(), t);
118
119        TimerHandle(tag)
120    }
121
122    /// Remove a timer.
123    pub(crate) fn remove(&self, tag: TimerHandle) {
124        let mut timer = self.timers.borrow_mut();
125        for i in 0..timer.len() {
126            if timer[i].tag == tag.0 {
127                timer.remove(i);
128                break;
129            }
130        }
131    }
132}
133
134/// Timing event data. Used by [TimerEvent].
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136pub struct TimeOut {
137    pub handle: TimerHandle,
138    pub counter: usize,
139}
140
141/// Holds the information to start a timer.
142#[derive(Debug, Default)]
143pub struct TimerDef {
144    /// Optional repeat.
145    repeat: Option<usize>,
146    /// Duration
147    timer: Duration,
148    /// Specific time.
149    next: Option<Instant>,
150}
151
152impl TimerDef {
153    pub fn new() -> Self {
154        Default::default()
155    }
156
157    /// Repeat forever.
158    pub fn repeat_forever(mut self) -> Self {
159        self.repeat = Some(usize::MAX);
160        self
161    }
162
163    /// Repeat count.
164    pub fn repeat(mut self, repeat: usize) -> Self {
165        self.repeat = Some(repeat);
166        self
167    }
168
169    /// Timer interval.
170    pub fn timer(mut self, timer: Duration) -> Self {
171        self.timer = timer;
172        self
173    }
174
175    /// Next time the timer is due. Can set a start delay for a repeating timer,
176    /// or as an oneshot event for a given instant.
177    pub fn next(mut self, next: Instant) -> Self {
178        self.next = Some(next);
179        self
180    }
181}