cros_async/
timer.rs

1// Copyright 2020 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::time::Duration;
6
7use base::Result as SysResult;
8use base::Timer;
9use base::TimerTrait;
10
11use crate::AsyncResult;
12use crate::Error;
13use crate::Executor;
14use crate::IntoAsync;
15use crate::IoSource;
16
17/// An async version of base::Timer.
18pub struct TimerAsync<T: TimerTrait + IntoAsync> {
19    pub(crate) io_source: IoSource<T>,
20}
21
22impl<T: TimerTrait + IntoAsync> TimerAsync<T> {
23    pub fn new(timer: T, ex: &Executor) -> AsyncResult<TimerAsync<T>> {
24        ex.async_from(timer)
25            .map(|io_source| TimerAsync { io_source })
26    }
27
28    /// Gets the next value from the timer.
29    ///
30    /// NOTE: on Windows, this may return/wake early. See `base::Timer` docs
31    /// for details.
32    pub async fn wait(&self) -> AsyncResult<()> {
33        self.wait_sys().await
34    }
35
36    /// Sets the timer to expire after `dur`. Cancels any existing timer.
37    pub fn reset_oneshot(&mut self, dur: Duration) -> SysResult<()> {
38        self.io_source.as_source_mut().reset_oneshot(dur)
39    }
40
41    /// Sets the timer to expire repeatedly at intervals of `dur`. Cancels any existing timer.
42    pub fn reset_repeating(&mut self, dur: Duration) -> SysResult<()> {
43        self.io_source.as_source_mut().reset_repeating(dur)
44    }
45
46    /// Disarms the timer.
47    pub fn clear(&mut self) -> SysResult<()> {
48        self.io_source.as_source_mut().clear()
49    }
50}
51
52impl TimerAsync<Timer> {
53    /// Async sleep for the given duration.
54    ///
55    /// NOTE: on Windows, this sleep may wake early. See `base::Timer` docs
56    /// for details.
57    pub async fn sleep(ex: &Executor, dur: Duration) -> std::result::Result<(), Error> {
58        let mut tfd = Timer::new().map_err(Error::Timer)?;
59        tfd.reset_oneshot(dur).map_err(Error::Timer)?;
60        let t = TimerAsync::new(tfd, ex).map_err(Error::TimerAsync)?;
61        t.wait().await.map_err(Error::TimerAsync)?;
62        Ok(())
63    }
64}
65
66impl IntoAsync for Timer {}