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