• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 use std::time::Duration;
6 
7 use base::Result as SysResult;
8 use base::Timer;
9 use base::TimerTrait;
10 
11 use crate::AsyncResult;
12 use crate::Error;
13 use crate::Executor;
14 use crate::IntoAsync;
15 use crate::IoSource;
16 
17 /// An async version of base::Timer.
18 pub struct TimerAsync<T: TimerTrait + IntoAsync> {
19     pub(crate) io_source: IoSource<T>,
20 }
21 
22 impl<T: TimerTrait + IntoAsync> TimerAsync<T> {
new(timer: T, ex: &Executor) -> AsyncResult<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.
wait(&self) -> AsyncResult<()>32     pub async fn wait(&self) -> AsyncResult<()> {
33         self.wait_sys().await
34     }
35 
36     /// Sets the timer to expire after `dur`.  If `interval` is not `None` and non-zero it
37     /// represents the period for repeated expirations after the initial expiration.  Otherwise
38     /// the timer will expire just once.  Cancels any existing duration and repeating interval.
reset(&mut self, dur: Duration, interval: Option<Duration>) -> SysResult<()>39     pub fn reset(&mut self, dur: Duration, interval: Option<Duration>) -> SysResult<()> {
40         self.io_source.as_source_mut().reset(dur, interval)
41     }
42 
43     /// Disarms the timer.
clear(&mut self) -> SysResult<()>44     pub fn clear(&mut self) -> SysResult<()> {
45         self.io_source.as_source_mut().clear()
46     }
47 }
48 
49 impl TimerAsync<Timer> {
50     /// Async sleep for the given duration.
51     ///
52     /// NOTE: on Windows, this sleep may wake early. See `base::Timer` docs
53     /// for details.
sleep(ex: &Executor, dur: Duration) -> std::result::Result<(), Error>54     pub async fn sleep(ex: &Executor, dur: Duration) -> std::result::Result<(), Error> {
55         let mut tfd = Timer::new().map_err(Error::Timer)?;
56         tfd.reset(dur, None).map_err(Error::Timer)?;
57         let t = TimerAsync::new(tfd, ex).map_err(Error::TimerAsync)?;
58         t.wait().await.map_err(Error::TimerAsync)?;
59         Ok(())
60     }
61 }
62 
63 impl IntoAsync for Timer {}
64