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::Event; 6 7 use crate::AsyncError; 8 use crate::AsyncResult; 9 use crate::EventAsync; 10 use crate::Executor; 11 12 impl EventAsync { new(event: Event, ex: &Executor) -> AsyncResult<EventAsync>13 pub fn new(event: Event, ex: &Executor) -> AsyncResult<EventAsync> { 14 ex.async_from(event) 15 .map(|io_source| EventAsync { io_source }) 16 } 17 18 /// Gets the next value from the eventfd. next_val(&self) -> AsyncResult<u64>19 pub async fn next_val(&self) -> AsyncResult<u64> { 20 let (n, v) = self 21 .io_source 22 .read_to_vec(None, 0u64.to_ne_bytes().to_vec()) 23 .await?; 24 if n != 8 { 25 return Err(AsyncError::EventAsync(base::Error::new(libc::ENODATA))); 26 } 27 Ok(u64::from_ne_bytes(v.try_into().unwrap())) 28 } 29 } 30 31 #[cfg(test)] 32 mod tests { 33 use std::sync::Arc; 34 35 use base::EventExt; 36 37 use super::super::fd_executor::EpollReactor; 38 use super::super::uring_executor::UringReactor; 39 use super::*; 40 use crate::common_executor::RawExecutor; 41 use crate::sys::linux::uring_executor::is_uring_stable; 42 use crate::ExecutorTrait; 43 new_poll( event: Event, ex: &Arc<RawExecutor<EpollReactor>>, ) -> AsyncResult<EventAsync>44 pub(crate) fn new_poll( 45 event: Event, 46 ex: &Arc<RawExecutor<EpollReactor>>, 47 ) -> AsyncResult<EventAsync> { 48 ex.async_from(event) 49 .map(|io_source| EventAsync { io_source }) 50 } 51 new_uring( event: Event, ex: &Arc<RawExecutor<UringReactor>>, ) -> AsyncResult<EventAsync>52 pub(crate) fn new_uring( 53 event: Event, 54 ex: &Arc<RawExecutor<UringReactor>>, 55 ) -> AsyncResult<EventAsync> { 56 ex.async_from(event) 57 .map(|io_source| EventAsync { io_source }) 58 } 59 60 #[test] next_val_reads_value()61 fn next_val_reads_value() { 62 async fn go(event: Event, ex: &Executor) -> u64 { 63 let event_async = EventAsync::new(event, ex).unwrap(); 64 event_async.next_val().await.unwrap() 65 } 66 67 let eventfd = Event::new().unwrap(); 68 eventfd.write_count(0xaa).unwrap(); 69 let ex = Executor::new().unwrap(); 70 let val = ex.run_until(go(eventfd, &ex)).unwrap(); 71 assert_eq!(val, 0xaa); 72 } 73 74 #[test] next_val_reads_value_poll_and_ring()75 fn next_val_reads_value_poll_and_ring() { 76 if !is_uring_stable() { 77 return; 78 } 79 80 async fn go(event_async: EventAsync) -> u64 { 81 event_async.next_val().await.unwrap() 82 } 83 84 let eventfd = Event::new().unwrap(); 85 eventfd.write_count(0xaa).unwrap(); 86 let uring_ex = RawExecutor::<UringReactor>::new().unwrap(); 87 let val = uring_ex 88 .run_until(go(new_uring(eventfd, &uring_ex).unwrap())) 89 .unwrap(); 90 assert_eq!(val, 0xaa); 91 92 let eventfd = Event::new().unwrap(); 93 eventfd.write_count(0xaa).unwrap(); 94 let poll_ex = RawExecutor::<EpollReactor>::new().unwrap(); 95 let val = poll_ex 96 .run_until(go(new_poll(eventfd, &poll_ex).unwrap())) 97 .unwrap(); 98 assert_eq!(val, 0xaa); 99 } 100 } 101