xref: /aosp_15_r20/external/crosvm/base/src/sys/windows/events.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 pub use super::wait::*;
6 use super::RawDescriptor;
7 use crate::descriptor::AsRawDescriptor;
8 use crate::EventToken;
9 
10 /// Represents descriptor-token pairs which represent an event which can be triggered in the
11 /// EventContext
12 #[derive(PartialEq, Eq)]
13 pub struct EventTrigger<T: EventToken> {
14     pub(crate) token: T,
15     pub(crate) event: RawDescriptor,
16 }
17 
18 impl<T: EventToken> EventTrigger<T> {
from(descriptor: &dyn AsRawDescriptor, token: T) -> Self19     pub fn from(descriptor: &dyn AsRawDescriptor, token: T) -> Self {
20         EventTrigger {
21             token,
22             event: descriptor.as_raw_descriptor(),
23         }
24     }
25 }
26 
27 impl<T: EventToken> Clone for EventTrigger<T> {
clone(&self) -> Self28     fn clone(&self) -> Self {
29         EventTrigger {
30             token: T::from_raw_token(self.token.as_raw_token()),
31             event: self.event,
32         }
33     }
34 }
35 
36 #[cfg(test)]
37 mod tests {
38     use std::time::Duration;
39 
40     use super::*;
41     use crate::Event;
42 
43     #[test]
event_context()44     fn event_context() {
45         let evt1 = Event::new().unwrap();
46         let evt2 = Event::new().unwrap();
47         evt1.signal().unwrap();
48         evt2.signal().unwrap();
49         let ctx: EventContext<u32> =
50             EventContext::build_with(&[EventTrigger::from(&evt1, 1), EventTrigger::from(&evt2, 2)])
51                 .unwrap();
52 
53         let mut evt_count = 0;
54         while evt_count < 2 {
55             for event in ctx.wait().unwrap().iter() {
56                 evt_count += 1;
57                 match event.token {
58                     1 => {
59                         evt1.wait().unwrap();
60                         ctx.delete(&evt1).unwrap();
61                     }
62                     2 => {
63                         evt2.wait().unwrap();
64                         ctx.delete(&evt2).unwrap();
65                     }
66                     _ => panic!("unexpected token"),
67                 };
68             }
69         }
70         assert_eq!(evt_count, 2);
71     }
72 
73     // TODO(145170451) rizhang: This test will be needed to be implemented when the round robn
74     // implementation is complete
75     // #[test]
76     // fn poll_context_overflow() {
77     //     const EVT_COUNT: usize = MAXIMUM_WAIT_OBJECTS * 2 + 1;
78     //     let ctx: EventContext<usize> = EventContext::new().unwrap();
79     //     let mut evts = Vec::with_capacity(EVT_COUNT);
80     //     for i in 0..EVT_COUNT {
81     //         let evt = Event::new().unwrap();
82     //         evt.signal().unwrap();
83     //         ctx.add(&evt, i).unwrap();
84     //         evts.push(evt);
85     //     }
86     //     let mut evt_count = 0;
87     //     while evt_count < EVT_COUNT {
88     //         for event in ctx.wait().unwrap().iter_readable() {
89     //             evts[event.token()].wait().unwrap();
90     //             evt_count += 1;
91     //         }
92     //     }
93     // }
94 
95     #[test]
poll_context_timeout()96     fn poll_context_timeout() {
97         let ctx: EventContext<u32> = EventContext::new().unwrap();
98         let evt = Event::new().unwrap();
99         ctx.add(EventTrigger::from(&evt, 1))
100             .expect("Failed to add event.");
101         let dur = Duration::from_millis(100);
102         let events = ctx.wait_timeout(dur).unwrap();
103         assert_eq!(events.len(), 0);
104     }
105 
106     #[test]
wait_returns_mulitple_signal_events()107     fn wait_returns_mulitple_signal_events() {
108         let evt1 = Event::new().unwrap();
109         let evt2 = Event::new().unwrap();
110         let evt3 = Event::new().unwrap();
111         evt1.signal().expect("Failed to write to event.");
112         evt2.signal().expect("Failed to write to event.");
113         evt3.signal().expect("Failed to write to event.");
114         let ctx: EventContext<u32> = EventContext::build_with(&[
115             EventTrigger::from(&evt1, 1),
116             EventTrigger::from(&evt2, 2),
117             EventTrigger::from(&evt3, 3),
118         ])
119         .unwrap();
120         let events = ctx.wait().unwrap();
121 
122         let tokens: Vec<u32> = events.iter().map(|e| e.token).collect();
123         assert_eq!(tokens.len(), 3);
124         assert_eq!(tokens, [1, 2, 3]);
125     }
126 
127     #[test]
wait_returns_mulitple_signal_and_unsignaled_events()128     fn wait_returns_mulitple_signal_and_unsignaled_events() {
129         let evt1 = Event::new().unwrap();
130         let evt2 = Event::new().unwrap();
131         let evt3 = Event::new().unwrap();
132         let evt4 = Event::new().unwrap();
133         let evt5 = Event::new().unwrap();
134         let evt6 = Event::new().unwrap();
135         let evt7 = Event::new().unwrap();
136         evt1.signal().unwrap();
137         evt2.signal().unwrap();
138         evt4.signal().unwrap();
139         evt7.signal().unwrap();
140         let ctx: EventContext<u32> = EventContext::build_with(&[
141             EventTrigger::from(&evt1, 1),
142             EventTrigger::from(&evt2, 2),
143             EventTrigger::from(&evt3, 3),
144             EventTrigger::from(&evt4, 4),
145             EventTrigger::from(&evt5, 5),
146             EventTrigger::from(&evt6, 6),
147             EventTrigger::from(&evt7, 7),
148         ])
149         .unwrap();
150         let events = ctx.wait().unwrap();
151 
152         let tokens: Vec<u32> = events.iter().map(|e| e.token).collect();
153         assert_eq!(tokens.len(), 4);
154         assert_eq!(tokens, [1, 2, 4, 7]);
155     }
156 }
157