xref: /aosp_15_r20/external/crosvm/cros_async/src/sys/linux/event.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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