hiver_runtime/driver/
interest.rs1#[allow(unused_imports)]
5use std::os::fd::RawFd;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13pub struct Interest {
14 pub readable: bool,
16 pub writable: bool,
18 pub priority: bool,
20 pub oneshot: bool,
22 pub edge: bool,
24}
25
26impl Interest {
27 #[must_use]
30 pub const fn new() -> Self {
31 Self {
32 readable: false,
33 writable: false,
34 priority: false,
35 oneshot: false,
36 edge: false,
37 }
38 }
39
40 #[must_use]
43 pub const fn readable() -> Self {
44 Self {
45 readable: true,
46 writable: false,
47 priority: false,
48 oneshot: false,
49 edge: false,
50 }
51 }
52
53 #[must_use]
56 pub const fn writable() -> Self {
57 Self {
58 readable: false,
59 writable: true,
60 priority: false,
61 oneshot: false,
62 edge: false,
63 }
64 }
65
66 #[must_use]
69 pub const fn both() -> Self {
70 Self {
71 readable: true,
72 writable: true,
73 priority: false,
74 oneshot: false,
75 edge: false,
76 }
77 }
78
79 #[must_use]
82 pub const fn with_readable(mut self) -> Self {
83 self.readable = true;
84 self
85 }
86
87 #[must_use]
90 pub const fn with_writable(mut self) -> Self {
91 self.writable = true;
92 self
93 }
94
95 #[must_use]
98 pub const fn with_priority(mut self) -> Self {
99 self.priority = true;
100 self
101 }
102
103 #[must_use]
106 pub const fn with_oneshot(mut self) -> Self {
107 self.oneshot = true;
108 self
109 }
110
111 #[must_use]
114 pub const fn with_edge(mut self) -> Self {
115 self.edge = true;
116 self
117 }
118
119 #[cfg(target_os = "linux")]
122 pub const fn to_epoll_flags(self) -> u32 {
123 let mut flags = 0u32;
124
125 if self.readable {
126 flags |= libc::EPOLLIN as u32;
127 }
128 if self.writable {
129 flags |= libc::EPOLLOUT as u32;
130 }
131 if self.priority {
132 flags |= libc::EPOLLPRI as u32;
133 }
134 if self.oneshot {
135 flags |= libc::EPOLLONESHOT as u32;
136 }
137 if self.edge {
138 flags |= libc::EPOLLET as u32;
139 }
140
141 flags
142 }
143
144 #[cfg(target_os = "linux")]
147 pub fn from_epoll_flags(flags: u32) -> Self {
148 Self {
149 readable: (flags & libc::EPOLLIN as u32) != 0,
150 writable: (flags & libc::EPOLLOUT as u32) != 0,
151 priority: (flags & libc::EPOLLPRI as u32) != 0,
152 oneshot: (flags & libc::EPOLLONESHOT as u32) != 0,
153 edge: (flags & libc::EPOLLET as u32) != 0,
154 }
155 }
156
157 #[cfg(any(
160 target_os = "macos",
161 target_os = "freebsd",
162 target_os = "netbsd",
163 target_os = "openbsd",
164 target_os = "dragonfly"
165 ))]
166 #[allow(dead_code)]
167 pub fn to_kqueue_filters(&self, fd: RawFd) -> (Vec<libc::kevent>, Vec<libc::kevent>) {
168 use std::mem::zeroed;
169
170 let mut add_events = Vec::with_capacity(2);
171 let remove_events = Vec::new();
172
173 if self.readable {
174 let mut event = unsafe { zeroed::<libc::kevent>() };
175 event.ident = fd as libc::uintptr_t;
176 event.filter = libc::EVFILT_READ;
177 event.flags = libc::EV_ADD | libc::EV_RECEIPT;
178 if self.edge {
179 event.flags |= libc::EV_CLEAR;
180 }
181 if self.oneshot {
182 event.flags |= libc::EV_ONESHOT;
183 }
184 add_events.push(event);
185 }
186
187 if self.writable {
188 let mut event = unsafe { zeroed::<libc::kevent>() };
189 event.ident = fd as libc::uintptr_t;
190 event.filter = libc::EVFILT_WRITE;
191 event.flags = libc::EV_ADD | libc::EV_RECEIPT;
192 if self.edge {
193 event.flags |= libc::EV_CLEAR;
194 }
195 if self.oneshot {
196 event.flags |= libc::EV_ONESHOT;
197 }
198 add_events.push(event);
199 }
200
201 (add_events, remove_events)
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 #[test]
210 fn test_interest_builder() {
211 let interest = Interest::readable().with_writable().with_edge();
212
213 assert!(interest.readable);
214 assert!(interest.writable);
215 assert!(interest.edge);
216 assert!(!interest.priority);
217 }
218
219 #[test]
220 fn test_interest_both() {
221 let interest = Interest::both();
222 assert!(interest.readable);
223 assert!(interest.writable);
224 }
225}