// Copyright 2020 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. use sys_util::EventFd; use crate::{AsyncResult, Executor, IntoAsync, IoSourceExt}; /// An async version of `sys_util::EventFd`. pub struct EventAsync { io_source: Box<dyn IoSourceExt<EventFd>>, } impl EventAsync { pub fn new(event: EventFd, ex: &Executor) -> AsyncResult<EventAsync> { ex.async_from(event) .map(|io_source| EventAsync { io_source }) } #[cfg(test)] pub(crate) fn new_poll(event: EventFd, ex: &crate::FdExecutor) -> AsyncResult<EventAsync> { crate::executor::async_poll_from(event, ex).map(|io_source| EventAsync { io_source }) } #[cfg(test)] pub(crate) fn new_uring(event: EventFd, ex: &crate::URingExecutor) -> AsyncResult<EventAsync> { crate::executor::async_uring_from(event, ex).map(|io_source| EventAsync { io_source }) } /// Gets the next value from the eventfd. #[allow(dead_code)] pub async fn next_val(&self) -> AsyncResult<u64> { self.io_source.read_u64().await } } impl IntoAsync for EventFd {} #[cfg(test)] mod tests { use super::*; use crate::{Executor, FdExecutor, URingExecutor}; #[test] fn next_val_reads_value() { async fn go(event: EventFd, ex: &Executor) -> u64 { let event_async = EventAsync::new(event, ex).unwrap(); event_async.next_val().await.unwrap() } let eventfd = EventFd::new().unwrap(); eventfd.write(0xaa).unwrap(); let ex = Executor::new().unwrap(); let val = ex.run_until(go(eventfd, &ex)).unwrap(); assert_eq!(val, 0xaa); } #[test] fn next_val_reads_value_poll_and_ring() { async fn go(event_async: EventAsync) -> u64 { event_async.next_val().await.unwrap() } let eventfd = EventFd::new().unwrap(); eventfd.write(0xaa).unwrap(); let uring_ex = URingExecutor::new().unwrap(); let val = uring_ex .run_until(go(EventAsync::new_uring(eventfd, &uring_ex).unwrap())) .unwrap(); assert_eq!(val, 0xaa); let eventfd = EventFd::new().unwrap(); eventfd.write(0xaa).unwrap(); let poll_ex = FdExecutor::new().unwrap(); let val = poll_ex .run_until(go(EventAsync::new_poll(eventfd, &poll_ex).unwrap())) .unwrap(); assert_eq!(val, 0xaa); } }