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