1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2024 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 use std::time::Duration; 6*bb4ee6a4SAndroid Build Coastguard Worker 7*bb4ee6a4SAndroid Build Coastguard Worker use crate::errno::Result; 8*bb4ee6a4SAndroid Build Coastguard Worker use crate::event::EventWaitResult; 9*bb4ee6a4SAndroid Build Coastguard Worker use crate::sys::macos::kqueue::make_kevent; 10*bb4ee6a4SAndroid Build Coastguard Worker use crate::sys::macos::kqueue::Kqueue; 11*bb4ee6a4SAndroid Build Coastguard Worker use crate::sys::unix::RawDescriptor; 12*bb4ee6a4SAndroid Build Coastguard Worker use crate::SafeDescriptor; 13*bb4ee6a4SAndroid Build Coastguard Worker 14*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] 15*bb4ee6a4SAndroid Build Coastguard Worker pub struct PlatformEvent { 16*bb4ee6a4SAndroid Build Coastguard Worker queue: Kqueue, 17*bb4ee6a4SAndroid Build Coastguard Worker } 18*bb4ee6a4SAndroid Build Coastguard Worker 19*bb4ee6a4SAndroid Build Coastguard Worker impl PlatformEvent { new() -> Result<PlatformEvent>20*bb4ee6a4SAndroid Build Coastguard Worker pub fn new() -> Result<PlatformEvent> { 21*bb4ee6a4SAndroid Build Coastguard Worker let event = PlatformEvent { 22*bb4ee6a4SAndroid Build Coastguard Worker queue: Kqueue::new()?, 23*bb4ee6a4SAndroid Build Coastguard Worker }; 24*bb4ee6a4SAndroid Build Coastguard Worker let reg = make_kevent( 25*bb4ee6a4SAndroid Build Coastguard Worker libc::EVFILT_USER, 26*bb4ee6a4SAndroid Build Coastguard Worker libc::EV_ADD | libc::EV_CLEAR, 27*bb4ee6a4SAndroid Build Coastguard Worker libc::NOTE_FFNOP, 28*bb4ee6a4SAndroid Build Coastguard Worker ); 29*bb4ee6a4SAndroid Build Coastguard Worker event.queue.kevent(&[reg], &mut [], None)?; 30*bb4ee6a4SAndroid Build Coastguard Worker Ok(event) 31*bb4ee6a4SAndroid Build Coastguard Worker } 32*bb4ee6a4SAndroid Build Coastguard Worker signal(&self) -> Result<()>33*bb4ee6a4SAndroid Build Coastguard Worker pub fn signal(&self) -> Result<()> { 34*bb4ee6a4SAndroid Build Coastguard Worker let event = make_kevent(libc::EVFILT_USER, 0, libc::NOTE_TRIGGER); 35*bb4ee6a4SAndroid Build Coastguard Worker self.queue.kevent(&[event], &mut [], None)?; 36*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 37*bb4ee6a4SAndroid Build Coastguard Worker } 38*bb4ee6a4SAndroid Build Coastguard Worker wait(&self) -> Result<()>39*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait(&self) -> Result<()> { 40*bb4ee6a4SAndroid Build Coastguard Worker let mut event = [make_kevent(0, 0, 0)]; 41*bb4ee6a4SAndroid Build Coastguard Worker self.queue.kevent(&[], &mut event[..], None)?; 42*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 43*bb4ee6a4SAndroid Build Coastguard Worker } 44*bb4ee6a4SAndroid Build Coastguard Worker wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult>45*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult> { 46*bb4ee6a4SAndroid Build Coastguard Worker let mut event = [make_kevent(0, 0, 0)]; 47*bb4ee6a4SAndroid Build Coastguard Worker if self.queue.kevent(&[], &mut event[..], Some(timeout))?.len() == 0 { 48*bb4ee6a4SAndroid Build Coastguard Worker Ok(EventWaitResult::TimedOut) 49*bb4ee6a4SAndroid Build Coastguard Worker } else { 50*bb4ee6a4SAndroid Build Coastguard Worker Ok(EventWaitResult::Signaled) 51*bb4ee6a4SAndroid Build Coastguard Worker } 52*bb4ee6a4SAndroid Build Coastguard Worker } 53*bb4ee6a4SAndroid Build Coastguard Worker reset(&self) -> Result<()>54*bb4ee6a4SAndroid Build Coastguard Worker pub fn reset(&self) -> Result<()> { 55*bb4ee6a4SAndroid Build Coastguard Worker self.wait_timeout(Duration::ZERO)?; 56*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker try_clone(&self) -> Result<PlatformEvent>59*bb4ee6a4SAndroid Build Coastguard Worker pub fn try_clone(&self) -> Result<PlatformEvent> { 60*bb4ee6a4SAndroid Build Coastguard Worker self.queue.try_clone().map(|queue| PlatformEvent { queue }) 61*bb4ee6a4SAndroid Build Coastguard Worker } 62*bb4ee6a4SAndroid Build Coastguard Worker } 63*bb4ee6a4SAndroid Build Coastguard Worker 64*bb4ee6a4SAndroid Build Coastguard Worker impl crate::AsRawDescriptor for PlatformEvent { as_raw_descriptor(&self) -> RawDescriptor65*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 66*bb4ee6a4SAndroid Build Coastguard Worker self.queue.as_raw_descriptor() 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker } 69*bb4ee6a4SAndroid Build Coastguard Worker 70*bb4ee6a4SAndroid Build Coastguard Worker impl crate::FromRawDescriptor for PlatformEvent { from_raw_descriptor(descriptor: RawDescriptor) -> Self71*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self { 72*bb4ee6a4SAndroid Build Coastguard Worker PlatformEvent { 73*bb4ee6a4SAndroid Build Coastguard Worker queue: Kqueue::from_raw_descriptor(descriptor), 74*bb4ee6a4SAndroid Build Coastguard Worker } 75*bb4ee6a4SAndroid Build Coastguard Worker } 76*bb4ee6a4SAndroid Build Coastguard Worker } 77*bb4ee6a4SAndroid Build Coastguard Worker 78*bb4ee6a4SAndroid Build Coastguard Worker impl crate::IntoRawDescriptor for PlatformEvent { into_raw_descriptor(self) -> RawDescriptor79*bb4ee6a4SAndroid Build Coastguard Worker fn into_raw_descriptor(self) -> RawDescriptor { 80*bb4ee6a4SAndroid Build Coastguard Worker self.queue.into_raw_descriptor() 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker } 83*bb4ee6a4SAndroid Build Coastguard Worker 84*bb4ee6a4SAndroid Build Coastguard Worker impl From<PlatformEvent> for SafeDescriptor { from(evt: PlatformEvent) -> Self85*bb4ee6a4SAndroid Build Coastguard Worker fn from(evt: PlatformEvent) -> Self { 86*bb4ee6a4SAndroid Build Coastguard Worker SafeDescriptor::from(evt.queue) 87*bb4ee6a4SAndroid Build Coastguard Worker } 88*bb4ee6a4SAndroid Build Coastguard Worker } 89*bb4ee6a4SAndroid Build Coastguard Worker 90*bb4ee6a4SAndroid Build Coastguard Worker impl From<SafeDescriptor> for PlatformEvent { from(queue: SafeDescriptor) -> Self91*bb4ee6a4SAndroid Build Coastguard Worker fn from(queue: SafeDescriptor) -> Self { 92*bb4ee6a4SAndroid Build Coastguard Worker PlatformEvent { 93*bb4ee6a4SAndroid Build Coastguard Worker queue: Kqueue::from(queue), 94*bb4ee6a4SAndroid Build Coastguard Worker } 95*bb4ee6a4SAndroid Build Coastguard Worker } 96*bb4ee6a4SAndroid Build Coastguard Worker } 97