1pub mod datagram;
2pub mod event;
3pub mod fd;
4pub mod fs;
5pub mod recv;
6pub mod socket;
7pub mod transfer;
8
9use std::{io, process};
10
11use self::{
12 event::{accept, creation, open, receiving},
13 fd::handles,
14};
15use crate::{
16 backend,
17 driver::{
18 self,
19 route::{self, kind},
20 },
21 platform,
22};
23
24type Buffer = <backend::Backend as platform::Buffer>::Token;
25
26#[must_use = "completion may own a resource that must be delivered or reclaimed"]
27pub(crate) struct Completion(CompletionKind);
28
29enum CompletionKind {
30 Shutdown,
31 AcceptSuccess {
32 token: route::Token,
33 accepted: handles::Accepted,
34 more: bool,
35 },
36 AcceptFailure {
37 token: route::Token,
38 errno: i32,
39 more: bool,
40 },
41 RecvData {
42 token: route::Token,
43 len: u32,
44 more: bool,
45 buffer: Buffer,
46 },
47 RecvExhausted {
48 token: route::Token,
49 more: bool,
50 },
51 Operation {
52 token: route::Token,
53 result: i32,
54 more: bool,
55 },
56 Opened {
57 token: route::Token,
58 opened: open::Opened,
59 },
60 OpenFailed {
61 token: route::Token,
62 error: open::Error,
63 },
64 SocketCreated {
65 token: route::Token,
66 slot: handles::FixedSlot,
67 },
68 SocketFailed {
69 token: route::Token,
70 errno: i32,
71 },
72}
73
74pub(crate) enum Reclaim<'d> {
75 Accepted(handles::Accepted),
76 Close(driver::Close<'d>),
77 Slots(driver::RetiredSlots<'d>),
78 Buffer(Buffer),
79 None,
80}
81
82impl Completion {
83 pub(crate) fn accepted(token: route::Token, accepted: handles::Accepted, more: bool) -> Self {
84 Self(CompletionKind::AcceptSuccess {
85 token,
86 accepted,
87 more,
88 })
89 }
90
91 pub(crate) fn accept_failed(token: route::Token, errno: i32, more: bool) -> Self {
92 Self(CompletionKind::AcceptFailure { token, errno, more })
93 }
94
95 pub(crate) fn shutdown() -> Self {
96 Self(CompletionKind::Shutdown)
97 }
98
99 pub(crate) fn operation(token: route::Token, result: i32, more: bool) -> Self {
100 Self(CompletionKind::Operation {
101 token,
102 result,
103 more,
104 })
105 }
106
107 pub(crate) fn opened(token: route::Token, opened: open::Opened) -> Self {
108 Self(CompletionKind::Opened { token, opened })
109 }
110
111 pub(crate) fn open_failed(token: route::Token, error: open::Error) -> Self {
112 Self(CompletionKind::OpenFailed { token, error })
113 }
114
115 pub(crate) fn socket_created(token: route::Token, slot: handles::FixedSlot) -> Self {
116 Self(CompletionKind::SocketCreated { token, slot })
117 }
118
119 pub(crate) fn socket_failure(token: route::Token, errno: i32) -> Self {
120 Self(CompletionKind::SocketFailed { token, errno })
121 }
122
123 pub(crate) fn received(token: route::Token, len: u32, more: bool, buffer: Buffer) -> Self {
124 debug_assert_eq!(token.kind(), kind::RECV);
125 Self(CompletionKind::RecvData {
126 token,
127 len,
128 more,
129 buffer,
130 })
131 }
132
133 pub(crate) fn recv_exhausted(token: route::Token, more: bool) -> Self {
134 debug_assert_eq!(token.kind(), kind::RECV);
135 Self(CompletionKind::RecvExhausted { token, more })
136 }
137
138 pub(crate) fn into_reclaim<'d>(self, reference: driver::Reference<'d>) -> Reclaim<'d> {
139 match self.0 {
140 CompletionKind::AcceptSuccess { accepted, .. } => Reclaim::Accepted(accepted),
141 CompletionKind::SocketCreated { slot, .. } => {
142 match reference.outbound().complete_outbound_create_success(slot) {
143 driver::CreateSuccess::Deliver(key) => {
144 match reference.outbound().begin_outbound_close(key, slot) {
145 driver::CloseDisposition::Submit(close) => Reclaim::Close(close),
146 driver::CloseDisposition::NoSubmit(Some(slots)) => {
147 Reclaim::Slots(slots)
148 }
149 driver::CloseDisposition::NoSubmit(None) => Reclaim::None,
150 }
151 }
152 driver::CreateSuccess::Close(close) => Reclaim::Close(close),
153 }
154 }
155 CompletionKind::RecvData { buffer, .. } => Reclaim::Buffer(buffer),
156 CompletionKind::Opened { opened, .. } => {
157 drop(opened);
158 Reclaim::None
159 }
160 CompletionKind::Shutdown
161 | CompletionKind::AcceptFailure { .. }
162 | CompletionKind::RecvExhausted { .. }
163 | CompletionKind::Operation { .. }
164 | CompletionKind::OpenFailed { .. }
165 | CompletionKind::SocketFailed { .. } => Reclaim::None,
166 }
167 }
168}
169
170pub enum RecvEvent<'d> {
171 Data(recv::Lease<'d>),
172 Eof,
173 Cancelled,
174 BufferExhausted,
175 Starved,
176 Failed(i32),
177}
178
179impl RecvEvent<'_> {
180 fn from_errno(result: i32) -> Self {
181 match -result {
182 libc::ECANCELED => Self::Cancelled,
183 libc::ENOBUFS | libc::EAGAIN | libc::EINTR => Self::Starved,
184 errno => Self::Failed(errno),
185 }
186 }
187}
188
189#[derive(Clone, Copy)]
190pub enum SendEvent {
191 Sent(u32),
192 Failed(i32),
193}
194
195#[derive(Clone, Copy)]
196pub enum ReadEvent {
197 Read(u32),
198 Eof,
199 Failed(i32),
200}
201
202#[derive(Clone, Copy)]
203pub enum WriteEvent {
204 Written(u32),
205 Failed(i32),
206}
207
208impl WriteEvent {
209 fn from_result(result: i32) -> Self {
210 if result >= 0 {
211 Self::Written(result as u32)
212 } else {
213 Self::Failed(-result)
214 }
215 }
216}
217
218impl ReadEvent {
219 fn from_result(result: i32) -> Self {
220 match result {
221 n if n > 0 => Self::Read(n as u32),
222 0 => Self::Eof,
223 n => Self::Failed(-n),
224 }
225 }
226}
227
228#[derive(Clone, Copy)]
229pub enum StatEvent {
230 Done,
231 Failed(i32),
232}
233
234#[derive(Clone, Copy)]
235pub enum Sync {
236 Done,
237 Failed(i32),
238}
239
240pub enum AcceptEvent<'d> {
241 Accepted(handles::AcceptedSlot<'d>),
242 Failed(i32),
243}
244
245pub enum SocketEvent<'d> {
246 Created(handles::CreatedSlot<'d>),
247 Failed(io::Error),
248}
249
250#[repr(transparent)]
268pub struct Event<'d>(event::Kind<'d>);
269
270const _: () =
271 assert!(std::mem::size_of::<Event<'static>>() == std::mem::size_of::<event::Kind<'static>>());
272
273impl<'d> Event<'d> {
274 pub(crate) fn from_completion(
275 completion: Completion,
276 reference: driver::Reference<'d>,
277 region: impl FnOnce(u32, &mut Buffer) -> recv::raw::Region,
278 ) -> Self {
279 use std::io::Error;
280
281 match completion.0 {
282 CompletionKind::Shutdown => Event(event::Kind::Shutdown),
283 CompletionKind::AcceptSuccess {
284 token,
285 accepted,
286 more,
287 } => {
288 let event = match accepted.bind(reference) {
289 Some(accepted) => AcceptEvent::Accepted(accepted),
290 None => AcceptEvent::Failed(libc::ECANCELED),
291 };
292 Event(event::Kind::Accept(
293 token,
294 accept::Completion::new(more, event),
295 ))
296 }
297 CompletionKind::AcceptFailure { token, errno, more } => Event(event::Kind::Accept(
298 token,
299 accept::Completion::new(more, AcceptEvent::Failed(errno)),
300 )),
301 CompletionKind::RecvData {
302 token,
303 len,
304 more,
305 mut buffer,
306 } => {
307 use crate::io::recv::Lease;
308
309 let region = region(len, &mut buffer);
310 let lease = Lease::from_completion(reference, buffer, region);
311 Event(event::Kind::Recv(receiving::Completion::new(
312 token,
313 more,
314 RecvEvent::Data(lease),
315 )))
316 }
317 CompletionKind::RecvExhausted { token, more } => Event(event::Kind::Recv(
318 receiving::Completion::new(token, more, RecvEvent::BufferExhausted),
319 )),
320 CompletionKind::Operation {
321 token,
322 result,
323 more,
324 } => Self::from_operation(token, result, more),
325 CompletionKind::Opened { token, opened } => Event(event::Kind::Open(
326 open::Completion::new(token, open::Outcome::Opened(opened)),
327 )),
328 CompletionKind::OpenFailed { token, error } => Event(event::Kind::Open(
329 open::Completion::new(token, open::Outcome::Failed(error.get())),
330 )),
331 CompletionKind::SocketCreated { token, slot } => {
332 Event(event::Kind::Socket(creation::Completion::new(
333 token,
334 match handles::Created::from_live(slot).bind(reference) {
335 Some(created) => SocketEvent::Created(created),
336 None => SocketEvent::Failed(Error::from_raw_os_error(libc::ECANCELED)),
337 },
338 )))
339 }
340 CompletionKind::SocketFailed { token, errno } => {
341 Event(event::Kind::Socket(creation::Completion::new(
342 token,
343 SocketEvent::Failed(Error::from_raw_os_error(errno)),
344 )))
345 }
346 }
347 }
348
349 fn from_operation(token: route::Token, result: i32, more: bool) -> Self {
350 use std::io::Error;
351
352 match token.kind() {
353 kind::RECV => {
354 let event = if result == 0 {
355 RecvEvent::Eof
356 } else {
357 RecvEvent::from_errno(result)
358 };
359 Self(event::Kind::Recv(receiving::Completion::new(
360 token, more, event,
361 )))
362 }
363 kind::SEND => {
364 use crate::io::event::send;
365
366 Self(event::Kind::Send(send::Completion::new(
367 token,
368 if result >= 0 {
369 SendEvent::Sent(result as u32)
370 } else {
371 SendEvent::Failed(-result)
372 },
373 )))
374 }
375 kind::READ => Self(event::Kind::Read(token, ReadEvent::from_result(result))),
376 kind::WRITE => Self(event::Kind::Write(token, WriteEvent::from_result(result))),
377 kind::STAT => Self(event::Kind::Stat(
378 token,
379 if result >= 0 {
380 StatEvent::Done
381 } else {
382 StatEvent::Failed(-result)
383 },
384 )),
385 kind::SYNC => Self(event::Kind::Sync(
386 token,
387 if result >= 0 {
388 Sync::Done
389 } else {
390 Sync::Failed(-result)
391 },
392 )),
393 kind::TUNING => {
394 use crate::io::event::tuning;
395
396 Self(event::Kind::Tuning(tuning::Completion::new(
397 token,
398 if result >= 0 {
399 tuning::Outcome::Applied
400 } else {
401 tuning::Outcome::Failed(Error::from_raw_os_error(-result))
402 },
403 )))
404 }
405 kind::CONNECT => {
406 use crate::io::event::connect;
407
408 Self(event::Kind::Connect(connect::Completion::new(
409 token,
410 if result >= 0 {
411 connect::Outcome::Connected
412 } else {
413 connect::Outcome::Failed(Error::from_raw_os_error(-result))
414 },
415 )))
416 }
417 _ => process::abort(),
418 }
419 }
420
421 pub const fn is_shutdown(&self) -> bool {
422 matches!(self.0, event::Kind::Shutdown)
423 }
424
425 pub const fn kind(&self) -> &event::Kind<'d> {
426 &self.0
427 }
428
429 pub fn into_kind(self) -> event::Kind<'d> {
430 self.0
431 }
432
433 pub const fn token(&self) -> Option<route::Token> {
434 match &self.0 {
435 event::Kind::Accept(token, ..)
436 | event::Kind::Read(token, _)
437 | event::Kind::Write(token, _)
438 | event::Kind::Stat(token, _)
439 | event::Kind::Sync(token, _) => Some(*token),
440 event::Kind::Recv(completion) => Some(completion.token()),
441 event::Kind::Send(completion) => Some(completion.token()),
442 event::Kind::Socket(completion) => Some(completion.token()),
443 event::Kind::Tuning(completion) => Some(completion.token()),
444 event::Kind::Connect(completion) => Some(completion.token()),
445 event::Kind::Open(completion) => Some(completion.token()),
446 event::Kind::Shutdown => None,
447 }
448 }
449
450 pub fn route(&self) -> u8 {
451 match &self.0 {
452 event::Kind::Accept(token, ..) => token.route(),
453 event::Kind::Recv(completion) => completion.token().route(),
454 event::Kind::Send(completion) => completion.token().route(),
455 event::Kind::Socket(completion) => completion.token().route(),
456 event::Kind::Tuning(completion) => completion.token().route(),
457 event::Kind::Connect(completion) => completion.token().route(),
458 event::Kind::Open(completion) => completion.token().route(),
459 event::Kind::Read(t, _) => t.route(),
460 event::Kind::Write(t, _) => t.route(),
461 event::Kind::Stat(t, _) => t.route(),
462 event::Kind::Sync(t, _) => t.route(),
463 event::Kind::Shutdown => route::SHUTDOWN.route(),
464 }
465 }
466}
467
468impl<'d> From<receiving::Completion<'d>> for Event<'d> {
469 fn from(completion: receiving::Completion<'d>) -> Self {
470 Self(event::Kind::Recv(completion))
471 }
472}