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