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