1 // Copyright 2020 The Chromium OS Authors. All rights reserved. 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 sys_util::EventFd; 6 7 use crate::{AsyncResult, Executor, IntoAsync, IoSourceExt}; 8 9 /// An async version of `sys_util::EventFd`. 10 pub struct EventAsync { 11 io_source: Box<dyn IoSourceExt<EventFd>>, 12 } 13 14 impl EventAsync { new(event: EventFd, ex: &Executor) -> AsyncResult<EventAsync>15 pub fn new(event: EventFd, ex: &Executor) -> AsyncResult<EventAsync> { 16 ex.async_from(event) 17 .map(|io_source| EventAsync { io_source }) 18 } 19 20 #[cfg(test)] new_poll(event: EventFd, ex: &crate::FdExecutor) -> AsyncResult<EventAsync>21 pub(crate) fn new_poll(event: EventFd, ex: &crate::FdExecutor) -> AsyncResult<EventAsync> { 22 crate::executor::async_poll_from(event, ex).map(|io_source| EventAsync { io_source }) 23 } 24 25 #[cfg(test)] new_uring(event: EventFd, ex: &crate::URingExecutor) -> AsyncResult<EventAsync>26 pub(crate) fn new_uring(event: EventFd, ex: &crate::URingExecutor) -> AsyncResult<EventAsync> { 27 crate::executor::async_uring_from(event, ex).map(|io_source| EventAsync { io_source }) 28 } 29 30 /// Gets the next value from the eventfd. 31 #[allow(dead_code)] next_val(&self) -> AsyncResult<u64>32 pub async fn next_val(&self) -> AsyncResult<u64> { 33 self.io_source.read_u64().await 34 } 35 } 36 37 impl IntoAsync for EventFd {} 38 39 #[cfg(test)] 40 mod tests { 41 use super::*; 42 43 use crate::{Executor, FdExecutor, URingExecutor}; 44 45 #[test] next_val_reads_value()46 fn next_val_reads_value() { 47 async fn go(event: EventFd, ex: &Executor) -> u64 { 48 let event_async = EventAsync::new(event, ex).unwrap(); 49 event_async.next_val().await.unwrap() 50 } 51 52 let eventfd = EventFd::new().unwrap(); 53 eventfd.write(0xaa).unwrap(); 54 let ex = Executor::new().unwrap(); 55 let val = ex.run_until(go(eventfd, &ex)).unwrap(); 56 assert_eq!(val, 0xaa); 57 } 58 59 #[test] next_val_reads_value_poll_and_ring()60 fn next_val_reads_value_poll_and_ring() { 61 async fn go(event_async: EventAsync) -> u64 { 62 event_async.next_val().await.unwrap() 63 } 64 65 let eventfd = EventFd::new().unwrap(); 66 eventfd.write(0xaa).unwrap(); 67 let uring_ex = URingExecutor::new().unwrap(); 68 let val = uring_ex 69 .run_until(go(EventAsync::new_uring(eventfd, &uring_ex).unwrap())) 70 .unwrap(); 71 assert_eq!(val, 0xaa); 72 73 let eventfd = EventFd::new().unwrap(); 74 eventfd.write(0xaa).unwrap(); 75 let poll_ex = FdExecutor::new().unwrap(); 76 let val = poll_ex 77 .run_until(go(EventAsync::new_poll(eventfd, &poll_ex).unwrap())) 78 .unwrap(); 79 assert_eq!(val, 0xaa); 80 } 81 } 82