1 // Copyright 2022 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 base::TimerTrait; 6 7 use crate::AsyncError; 8 use crate::AsyncResult; 9 use crate::IntoAsync; 10 use crate::TimerAsync; 11 12 impl<T: TimerTrait + IntoAsync> TimerAsync<T> { wait_sys(&self) -> AsyncResult<()>13 pub async fn wait_sys(&self) -> AsyncResult<()> { 14 let (n, _) = self 15 .io_source 16 .read_to_vec(None, 0u64.to_ne_bytes().to_vec()) 17 .await?; 18 if n != 8 { 19 return Err(AsyncError::EventAsync(base::Error::new(libc::ENODATA))); 20 } 21 Ok(()) 22 } 23 } 24 25 #[cfg(test)] 26 mod tests { 27 use std::sync::Arc; 28 use std::time::Duration; 29 use std::time::Instant; 30 31 use base::Timer; 32 33 use super::super::fd_executor::EpollReactor; 34 use super::super::uring_executor::UringReactor; 35 use super::*; 36 use crate::common_executor::RawExecutor; 37 use crate::sys::linux::uring_executor::is_uring_stable; 38 use crate::Executor; 39 use crate::ExecutorTrait; 40 41 impl TimerAsync<Timer> { new_poll( timer: Timer, ex: &Arc<RawExecutor<EpollReactor>>, ) -> AsyncResult<TimerAsync<Timer>>42 pub(crate) fn new_poll( 43 timer: Timer, 44 ex: &Arc<RawExecutor<EpollReactor>>, 45 ) -> AsyncResult<TimerAsync<Timer>> { 46 ex.async_from(timer) 47 .map(|io_source| TimerAsync { io_source }) 48 } 49 new_uring( timer: Timer, ex: &Arc<RawExecutor<UringReactor>>, ) -> AsyncResult<TimerAsync<Timer>>50 pub(crate) fn new_uring( 51 timer: Timer, 52 ex: &Arc<RawExecutor<UringReactor>>, 53 ) -> AsyncResult<TimerAsync<Timer>> { 54 ex.async_from(timer) 55 .map(|io_source| TimerAsync { io_source }) 56 } 57 } 58 59 #[test] timer()60 fn timer() { 61 async fn this_test(ex: &Executor) { 62 let dur = Duration::from_millis(200); 63 let now = Instant::now(); 64 TimerAsync::sleep(ex, dur).await.expect("unable to sleep"); 65 assert!(now.elapsed() >= dur); 66 } 67 68 let ex = Executor::new().expect("creating an executor failed"); 69 ex.run_until(this_test(&ex)).unwrap(); 70 } 71 72 #[test] one_shot()73 fn one_shot() { 74 if !is_uring_stable() { 75 return; 76 } 77 78 async fn this_test(ex: &Arc<RawExecutor<UringReactor>>) { 79 let mut tfd = Timer::new().expect("failed to create timerfd"); 80 81 let dur = Duration::from_millis(200); 82 let now = Instant::now(); 83 tfd.reset_oneshot(dur).expect("failed to arm timer"); 84 85 let t = TimerAsync::new_uring(tfd, ex).unwrap(); 86 t.wait().await.expect("unable to wait for timer"); 87 88 assert!(now.elapsed() >= dur); 89 } 90 91 let ex = RawExecutor::<UringReactor>::new().unwrap(); 92 ex.run_until(this_test(&ex)).unwrap(); 93 } 94 95 #[test] one_shot_fd()96 fn one_shot_fd() { 97 async fn this_test(ex: &Arc<RawExecutor<EpollReactor>>) { 98 let mut tfd = Timer::new().expect("failed to create timerfd"); 99 100 let dur = Duration::from_millis(200); 101 let now = Instant::now(); 102 tfd.reset_oneshot(dur).expect("failed to arm timer"); 103 104 let t = TimerAsync::new_poll(tfd, ex).unwrap(); 105 t.wait().await.expect("unable to wait for timer"); 106 107 assert!(now.elapsed() >= dur); 108 } 109 110 let ex = RawExecutor::<EpollReactor>::new().unwrap(); 111 ex.run_until(this_test(&ex)).unwrap(); 112 } 113 } 114