• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 super::{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: &super::FdExecutor) -> AsyncResult<EventAsync>21     pub(crate) fn new_poll(event: EventFd, ex: &super::FdExecutor) -> AsyncResult<EventAsync> {
22         super::executor::async_poll_from(event, ex).map(|io_source| EventAsync { io_source })
23     }
24 
25     #[cfg(test)]
new_uring(event: EventFd, ex: &super::URingExecutor) -> AsyncResult<EventAsync>26     pub(crate) fn new_uring(event: EventFd, ex: &super::URingExecutor) -> AsyncResult<EventAsync> {
27         super::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 super::super::{uring_executor::use_uring, 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         if !use_uring() {
62             return;
63         }
64 
65         async fn go(event_async: EventAsync) -> u64 {
66             event_async.next_val().await.unwrap()
67         }
68 
69         let eventfd = EventFd::new().unwrap();
70         eventfd.write(0xaa).unwrap();
71         let uring_ex = URingExecutor::new().unwrap();
72         let val = uring_ex
73             .run_until(go(EventAsync::new_uring(eventfd, &uring_ex).unwrap()))
74             .unwrap();
75         assert_eq!(val, 0xaa);
76 
77         let eventfd = EventFd::new().unwrap();
78         eventfd.write(0xaa).unwrap();
79         let poll_ex = FdExecutor::new().unwrap();
80         let val = poll_ex
81             .run_until(go(EventAsync::new_poll(eventfd, &poll_ex).unwrap()))
82             .unwrap();
83         assert_eq!(val, 0xaa);
84     }
85 }
86