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