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