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