Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/base/src/sys/macos/kqueue.rs
5394 views
1
// Copyright 2024 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 std::ptr;
6
use std::time::Duration;
7
8
use crate::descriptor::AsRawDescriptor;
9
use crate::descriptor::FromRawDescriptor;
10
use crate::errno::errno_result;
11
use crate::errno::Error;
12
use crate::errno::Result;
13
use crate::sys::unix::RawDescriptor;
14
use crate::unix::duration_to_timespec;
15
use crate::unix::set_descriptor_cloexec;
16
use crate::SafeDescriptor;
17
18
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
19
pub(in crate::sys::macos) struct Kqueue {
20
queue: SafeDescriptor,
21
}
22
23
// Only accepts the subset of parameters we actually use
24
pub(in crate::sys::macos) fn make_kevent(filter: i16, flags: u16, fflags: u32) -> libc::kevent64_s {
25
libc::kevent64_s {
26
ident: 0, /* hopefully not global? */
27
filter,
28
flags,
29
fflags,
30
data: 0,
31
udata: 0,
32
ext: [0, 0],
33
}
34
}
35
36
impl Kqueue {
37
pub(in crate::sys::macos) fn new() -> Result<Kqueue> {
38
// SAFETY: Trivially safe
39
let raw_queue = unsafe { libc::kqueue() };
40
if raw_queue < 0 {
41
return crate::errno::errno_result();
42
}
43
// SAFETY: Tested whether it was a valid file descriptor
44
let queue = unsafe { SafeDescriptor::from_raw_descriptor(raw_queue) };
45
set_descriptor_cloexec(&queue)?;
46
Ok(Kqueue { queue })
47
}
48
49
pub(in crate::sys::macos) fn kevent<'a>(
50
&self,
51
changelist: &[libc::kevent64_s],
52
eventlist: &'a mut [libc::kevent64_s],
53
timeout: Option<Duration>,
54
) -> Result<&'a mut [libc::kevent64_s]> {
55
let timespec = timeout.map(duration_to_timespec);
56
// SAFETY: `queue` is a valid kqueue, `changelist` and `eventlist` are supplied with lengths
57
// based on valid slices
58
let res = unsafe {
59
libc::kevent64(
60
self.queue.as_raw_descriptor(),
61
changelist.as_ptr(),
62
changelist.len() as i32,
63
eventlist.as_mut_ptr(),
64
eventlist.len() as i32,
65
0,
66
if let Some(timeout) = timespec {
67
&timeout
68
} else {
69
ptr::null()
70
},
71
)
72
};
73
if res < 0 {
74
return errno_result();
75
}
76
let returned_events = eventlist.split_at_mut(res as usize).0;
77
for event in returned_events.iter() {
78
if event.flags & libc::EV_ERROR != 0 {
79
return Err(Error::new(event.data));
80
}
81
}
82
Ok(returned_events)
83
}
84
85
pub(in crate::sys::macos) fn try_clone(&self) -> Result<Kqueue> {
86
self.queue.try_clone().map(|queue| Kqueue { queue })
87
}
88
}
89
90
impl crate::AsRawDescriptor for Kqueue {
91
fn as_raw_descriptor(&self) -> RawDescriptor {
92
self.queue.as_raw_descriptor()
93
}
94
}
95
96
impl crate::FromRawDescriptor for Kqueue {
97
unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self {
98
Kqueue {
99
queue: SafeDescriptor::from_raw_descriptor(descriptor),
100
}
101
}
102
}
103
104
impl crate::IntoRawDescriptor for Kqueue {
105
fn into_raw_descriptor(self) -> RawDescriptor {
106
self.queue.into_raw_descriptor()
107
}
108
}
109
110
impl From<Kqueue> for crate::SafeDescriptor {
111
fn from(queue: Kqueue) -> Self {
112
queue.queue
113
}
114
}
115
116
impl From<SafeDescriptor> for Kqueue {
117
fn from(queue: SafeDescriptor) -> Self {
118
Kqueue { queue }
119
}
120
}
121
122