xref: /aosp_15_r20/external/crosvm/cros_async/src/timer.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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`. Cancels any existing timer.
reset_oneshot(&mut self, dur: Duration) -> SysResult<()>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.
reset_repeating(&mut self, dur: Duration) -> SysResult<()>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.
clear(&mut self) -> SysResult<()>47     pub fn clear(&mut self) -> SysResult<()> {
48         self.io_source.as_source_mut().clear()
49     }
50 }
51 
52 impl 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.
sleep(ex: &Executor, dur: Duration) -> std::result::Result<(), Error>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 
66 impl IntoAsync for Timer {}
67