1pub mod datagram;
2pub mod fd;
3pub(crate) mod ffi;
4pub mod file;
5pub mod pipe;
6pub mod provided;
7pub mod socket;
8
9use std::error::Error as StdError;
10use std::fmt;
11use std::io::Error;
12use std::os::fd::OwnedFd;
13
14use crate::driver::DriverRef;
15use crate::driver::token::kind::ACCEPT;
16use crate::driver::token::kind::CONNECT;
17use crate::driver::token::kind::OPEN;
18use crate::driver::token::kind::READ;
19use crate::driver::token::kind::RECV;
20use crate::driver::token::kind::RECV_DISCARD;
21use crate::driver::token::kind::SEND;
22use crate::driver::token::kind::SOCKET;
23use crate::driver::token::kind::STAT;
24use crate::driver::token::kind::SYNC;
25use crate::driver::token::kind::TIMER;
26use crate::driver::token::kind::WRITE;
27use crate::driver::token::{SHUTDOWN, Token};
28use fd::AcceptedSlot;
29use ffi::Handle;
30use libc::EAGAIN;
31use libc::ECANCELED;
32use libc::EINTR;
33use libc::ENOBUFS;
34use provided::ProvidedLease;
35use provided::raw::completion::CompletedBuffer;
36use std::fmt::Display;
37use std::fmt::Formatter;
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq)]
40pub struct DecodeError;
41
42impl Display for DecodeError {
43 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
44 f.write_str("invalid completion")
45 }
46}
47
48impl StdError for DecodeError {}
49
50pub(crate) const BUFFER: u32 = 1 << 0;
51pub(crate) const MORE: u32 = 1 << 1;
52pub(crate) const BUFFER_SHIFT: u32 = 16;
53
54#[derive(Clone, Copy)]
55pub(crate) struct Cqe {
56 token: Token,
57 result: i32,
58 flags: u32,
59}
60
61impl Cqe {
62 pub(crate) const fn new(token: Token, result: i32, flags: u32) -> Self {
63 Self {
64 token,
65 result,
66 flags,
67 }
68 }
69
70 pub(crate) fn kind(self) -> u8 {
71 self.token.kind()
72 }
73
74 fn more(self) -> bool {
75 self.flags & MORE != 0
76 }
77
78 fn bid_raw(self) -> u16 {
79 (self.flags >> BUFFER_SHIFT) as u16
80 }
81
82 fn has_buffer(self) -> bool {
83 self.flags & BUFFER != 0
84 }
85}
86
87pub enum RecvEvent<'d> {
88 Data(ProvidedLease<'d>),
89 Discarded { len: u32 },
90 Eof,
91 Cancelled,
92 Starved,
93 Failed(i32),
94}
95
96impl RecvEvent<'_> {
97 fn from_errno(result: i32) -> Self {
98 match -result {
99 ECANCELED => Self::Cancelled,
100 ENOBUFS | EAGAIN | EINTR => Self::Starved,
101 errno => Self::Failed(errno),
102 }
103 }
104}
105
106#[derive(Clone, Copy)]
107pub enum SendEvent {
108 Sent(u32),
109 Failed(i32),
110}
111
112#[derive(Clone, Copy)]
113pub enum WriteEvent {
114 Wrote(u32),
115 Failed(i32),
116}
117
118#[derive(Clone, Copy)]
119pub enum SyncEvent {
120 Synced,
121 Failed(i32),
122}
123
124pub enum OpenEvent {
125 Opened(OwnedFd),
126 Failed(i32),
127}
128
129#[derive(Clone, Copy)]
130pub enum ReadEvent {
131 Read(u32),
132 Eof,
133 Failed(i32),
134}
135
136impl ReadEvent {
137 fn from_result(result: i32) -> Self {
138 match result {
139 n if n > 0 => Self::Read(n as u32),
140 0 => Self::Eof,
141 n => Self::Failed(-n),
142 }
143 }
144}
145
146#[derive(Clone, Copy)]
147pub enum StatEvent {
148 Done,
149 Failed(i32),
150}
151
152#[derive(Clone, Copy)]
153pub struct TimerEvent(i32);
154
155impl TimerEvent {
156 const fn from_result(result: i32) -> Self {
157 Self(result)
158 }
159
160 pub const fn raw_result(self) -> i32 {
161 self.0
162 }
163
164 pub const fn is_cancelled(self) -> bool {
165 self.0 == -ECANCELED
166 }
167}
168
169pub enum AcceptEvent<'d> {
170 Accepted(AcceptedSlot<'d>),
171 Failed(i32),
172}
173
174pub enum SocketEvent {
175 Created,
176 Failed(Error),
177}
178
179pub enum ConnectEvent {
180 Connected,
181 Failed(Error),
182}
183
184pub enum Event<'d> {
185 Accept(Token, bool, AcceptEvent<'d>),
186 Recv(Token, bool, RecvEvent<'d>),
187 Send(Token, SendEvent),
188 Timer(Token, TimerEvent),
189 Socket(Token, SocketEvent),
190 Connect(Token, ConnectEvent),
191 Write(Token, WriteEvent),
192 Sync(Token, SyncEvent),
193 Open(Token, OpenEvent),
194 Read(Token, ReadEvent),
195 Stat(Token, StatEvent),
196 Shutdown,
197}
198
199impl<'d> Event<'d> {
200 pub(crate) fn from_cqe(
201 cqe: Cqe,
202 reference: DriverRef<'d>,
203 provided: impl FnOnce(u32, u16) -> Option<CompletedBuffer>,
204 ) -> Result<Self, DecodeError> {
205 let result = cqe.result;
206 let operation = cqe.kind();
207 let mut provided = cqe
208 .has_buffer()
209 .then(|| provided(result.max(0) as u32, cqe.bid_raw()))
210 .flatten()
211 .map(|completed| ProvidedLease::from_completion(reference, completed));
212 let token = cqe.token;
213 let event = if token == SHUTDOWN {
214 Event::Shutdown
215 } else {
216 match operation {
217 ACCEPT => {
218 let event = if result >= 0 {
219 let slot = reference.fixed_fd_slot(result as u32).ok_or(DecodeError)?;
220 AcceptEvent::Accepted(AcceptedSlot::from_completion(slot, reference))
221 } else {
222 AcceptEvent::Failed(-result)
223 };
224 Event::Accept(token, cqe.more(), event)
225 }
226 RECV => {
227 let event = if result > 0 {
228 if !cqe.has_buffer() {
229 debug_assert!(false, "RECV data cqe without buffer flag");
230 return Err(DecodeError);
231 }
232 let lease = provided.take().ok_or(DecodeError)?;
233 debug_assert_eq!(lease.as_slice().len(), result as usize);
234 RecvEvent::Data(lease)
235 } else if result == 0 {
236 RecvEvent::Eof
237 } else {
238 RecvEvent::from_errno(result)
239 };
240 Event::Recv(token, cqe.more(), event)
241 }
242 RECV_DISCARD => {
243 let event = if result > 0 {
244 RecvEvent::Discarded { len: result as u32 }
245 } else if result == 0 {
246 RecvEvent::Eof
247 } else {
248 RecvEvent::from_errno(result)
249 };
250 Event::Recv(token, cqe.more(), event)
251 }
252 SEND => Event::Send(
253 token,
254 if result >= 0 {
255 SendEvent::Sent(result as u32)
256 } else {
257 SendEvent::Failed(-result)
258 },
259 ),
260 WRITE => Event::Write(
261 token,
262 if result >= 0 {
263 WriteEvent::Wrote(result as u32)
264 } else {
265 WriteEvent::Failed(-result)
266 },
267 ),
268 SYNC => Event::Sync(
269 token,
270 if result >= 0 {
271 SyncEvent::Synced
272 } else {
273 SyncEvent::Failed(-result)
274 },
275 ),
276 OPEN => Event::Open(
277 token,
278 if result >= 0 {
279 OpenEvent::Opened(Handle::take(result).into_owned())
280 } else {
281 OpenEvent::Failed(-result)
282 },
283 ),
284 READ => Event::Read(token, ReadEvent::from_result(result)),
285 STAT => Event::Stat(
286 token,
287 if result >= 0 {
288 StatEvent::Done
289 } else {
290 StatEvent::Failed(-result)
291 },
292 ),
293 TIMER => Event::Timer(token, TimerEvent::from_result(result)),
294 SOCKET => Event::Socket(
295 token,
296 if result >= 0 {
297 SocketEvent::Created
298 } else {
299 SocketEvent::Failed(Error::from_raw_os_error(-result))
300 },
301 ),
302 CONNECT => Event::Connect(
303 token,
304 if result >= 0 {
305 ConnectEvent::Connected
306 } else {
307 ConnectEvent::Failed(Error::from_raw_os_error(-result))
308 },
309 ),
310 _ => return Err(DecodeError),
311 }
312 };
313 Ok(event)
314 }
315
316 pub const fn is_shutdown(&self) -> bool {
317 matches!(self, Event::Shutdown)
318 }
319
320 pub const fn token(&self) -> Option<Token> {
321 match self {
322 Event::Accept(token, ..)
323 | Event::Recv(token, ..)
324 | Event::Send(token, _)
325 | Event::Timer(token, _)
326 | Event::Socket(token, _)
327 | Event::Connect(token, _)
328 | Event::Write(token, _)
329 | Event::Sync(token, _)
330 | Event::Open(token, _)
331 | Event::Read(token, _)
332 | Event::Stat(token, _) => Some(*token),
333 Event::Shutdown => None,
334 }
335 }
336
337 pub fn route(&self) -> u8 {
338 match self {
339 Event::Accept(t, ..) => t.route(),
340 Event::Recv(t, ..) => t.route(),
341 Event::Send(t, _) => t.route(),
342 Event::Timer(t, _) => t.route(),
343 Event::Socket(t, _) => t.route(),
344 Event::Connect(t, _) => t.route(),
345 Event::Write(t, _) => t.route(),
346 Event::Sync(t, _) => t.route(),
347 Event::Open(t, _) => t.route(),
348 Event::Read(t, _) => t.route(),
349 Event::Stat(t, _) => t.route(),
350 Event::Shutdown => SHUTDOWN.route(),
351 }
352 }
353}