async_timer/
interval.rs

1//!Interval module
2
3use core::future::Future;
4use core::{task, time};
5use core::pin::Pin;
6
7use crate::oneshot::Oneshot;
8use crate::oneshot::Timer as PlatformTimer;
9
10///Periodic Timer
11///
12///On each completition, underlying timer is restarted and therefore `Future` can be polled once
13///more.
14///
15///## Usage
16///
17///```rust, no_run
18///async fn job() {
19///}
20///
21///async fn do_a_while() {
22///    let mut times: u8 = 0;
23///    let mut interval = async_timer::Interval::platform_new(core::time::Duration::from_secs(1));
24///
25///    while times < 5 {
26///        job().await;
27///        interval.as_mut().await;
28///        times += 1;
29///    }
30///}
31///```
32#[must_use = "Interval does nothing unless polled"]
33pub struct Interval<T=PlatformTimer> {
34    timer: T,
35    ///Timer interval, change to this value will be reflected on next restart of timer.
36    pub interval: time::Duration,
37}
38
39impl Interval {
40    #[inline(always)]
41    ///Creates new instance using platform timer
42    pub fn platform_new(interval: time::Duration) -> Self {
43        Interval::<PlatformTimer>::new(interval)
44    }
45}
46
47impl<T: Oneshot> Interval<T> {
48    ///Creates new instance with specified timer type.
49    pub fn new(interval: time::Duration) -> Self {
50        Self {
51            timer: T::new(interval),
52            interval,
53        }
54    }
55
56    #[inline(always)]
57    ///Stops interval
58    pub fn cancel(&mut self) {
59        self.timer.cancel()
60    }
61
62    ///Restarts interval
63    pub fn restart(&mut self, ctx: &task::Context) {
64        let interval = self.interval;
65        self.timer.restart(interval, ctx.waker());
66    }
67
68
69    #[inline(always)]
70    ///Gets mutable reference
71    pub fn as_mut(&mut self) -> &mut Self {
72        self
73    }
74}
75
76impl<T: Oneshot> Future for &'_ mut Interval<T> {
77    type Output = ();
78
79    fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Self::Output> {
80        match Future::poll(Pin::new(&mut self.timer), ctx) {
81            task::Poll::Ready(()) => {
82                self.restart(ctx);
83                task::Poll::Ready(())
84            },
85            task::Poll::Pending => task::Poll::Pending,
86        }
87    }
88}
89
90#[cfg(feature = "stream")]
91impl<T: Oneshot> futures_core::stream::Stream for Interval<T> {
92    type Item = ();
93
94    #[inline]
95    fn poll_next(self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Option<Self::Item>> {
96        let mut this = self.get_mut();
97        Future::poll(Pin::new(&mut this), ctx).map(|res| Some(res))
98    }
99}