1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// Copyright (c) 2026 Mike Grier
//! Owned buffers an operation can borrow from the kernel's point of view.
//!
//! # Why owned, and not a slice
//!
//! Completion-based I/O touches the caller's memory *after* the submitting call
//! returns: `WriteFile` reads the buffer while the submitting thread has already
//! moved on, and the completion arrives later. A `&[u8]` cannot describe that.
//! Its borrow would have to span the whole operation, and nothing in the API can
//! make it: the submission token has no `Drop` that cancels, and even one would
//! be defeated by `mem::forget`, so a caller could always end the borrow with the
//! kernel still reading. A cancel-on-drop that *blocked* would be sound and would
//! also defeat the point of submitting asynchronously.
//!
//! So the buffer is handed over instead -- a protracted borrow, made out of
//! ownership rather than a lifetime. The operation holds it for exactly as long
//! as the kernel might touch it, and returns it on completion, through
//! `claim` or through [`crate::Started::Completed`]. The blocking adapters take
//! plain slices precisely because they do not have this problem: they block for
//! the whole operation, so an ordinary borrow provably covers it.
//!
//! # Why a trait, and not `Vec<u8>`
//!
//! Hardcoding `Vec<u8>` would mean a caller holding anything else -- a
//! `Box<[u8]>`, an `Arc<[u8]>`, an alignment-constrained buffer, one from a pool
//! -- has to convert, and every one of those conversions is a copy of exactly the
//! data this crate exists to move without copying. These traits let a caller hand
//! over whatever it already has.
//!
//! # Why `unsafe`
//!
//! The whole contract is a promise the compiler cannot check: the address must
//! stay put. A type whose accessor returns a fresh address on each call, or that
//! reallocates while the operation is in flight, is what makes the kernel write
//! into freed memory long after the call that started it returned. Implementing
//! these traits is asserting that cannot happen.
use Arc;
/// An owned buffer an operation reads bytes **from** (a write, a send).
///
/// # Safety
///
/// Implementors guarantee that, for as long as the value is owned by an
/// operation:
///
/// - [`IoBuf::stable_ptr`] returns the same address every time it is called, and
/// that address does not change when the value is moved. This is what a
/// pointer-to-heap buffer gives for free and an inline array does not: moving a
/// `[u8; N]` moves its bytes.
/// - The [`IoBuf::bytes_len`] bytes starting at that address stay allocated,
/// initialized, and unmodified.
/// - [`IoBuf::bytes_len`] returns the same value every time it is called.
///
/// `Send` because the operation's storage is reclaimed by whichever thread
/// dequeues the completion, which is not the submitting one; `'static` because
/// that storage is leaked to the kernel and carries no lifetime to check.
pub unsafe
/// An owned buffer an operation writes bytes **into** (a read, a receive).
///
/// Separate from [`IoBuf`] because not every owned buffer can be written to: an
/// `Arc<[u8]>` is perfectly good to send *from* and can never be a destination,
/// since handing out `&mut` to shared bytes would be unsound. Requiring one trait
/// for both would either exclude shared buffers from writes or let them be used
/// as read destinations.
///
/// # Safety
///
/// As [`IoBuf`], and additionally: the value must have exclusive access to the
/// [`IoBuf::bytes_len`] bytes at [`IoBufMut::stable_mut_ptr`], which must be the
/// same address [`IoBuf::stable_ptr`] reports, so the kernel writing into them
/// cannot race or alias anything else.
///
/// Those bytes must already be **initialized**. This crate does not track an
/// initialized prefix: a caller-supplied buffer is initialized once and reused
/// for the life of a pool, so the cost is per-pool rather than per-operation, and
/// the API carries no `set_init`-style obligation to forget.
pub unsafe
// SAFETY: a `Vec`'s bytes live in a heap allocation whose address is independent
// of where the `Vec` itself sits, so moving the `Vec` does not move them. Nothing
// here reallocates: the operation only reads and writes within `len`, never
// pushes. All `len` bytes are initialized by construction.
unsafe
// SAFETY: as the `IoBuf` impl; `&mut self` proves exclusive access, and
// `as_mut_ptr` returns the same allocation `as_ptr` does.
unsafe
// SAFETY: a boxed slice is a heap allocation of fixed length; moving the `Box`
// moves the pointer, not the bytes. Its length cannot change at all.
unsafe
// SAFETY: as above; `Box` is a unique owner, so `&mut self` is exclusive access.
unsafe
// SAFETY: the bytes live in the `Arc`'s allocation, which outlives every clone
// and never moves. Read-only by nature, which is why there is no `IoBufMut`
// counterpart: other clones may be reading the same bytes concurrently, so
// handing the kernel a writable pointer to them would alias.
unsafe
// SAFETY: a `'static` slice's referent is valid forever and never moves. Not
// writable for the same reason as `Arc<[u8]>`: the reference is shared.
unsafe
// SAFETY: as `&'static [u8]` -- the referent is valid forever and never moves,
// and the reference itself moving does not move the bytes.
unsafe
// SAFETY: the one reference type that *is* a legal read destination. Unlike
// `Arc<[u8]>` and `&'static [u8]`, a `&'static mut` is exclusive by
// construction -- no other live reference to those bytes can exist -- so the
// kernel writing into them cannot race or alias anything. Excluding it would be
// the arbitrary half of the split, not a safety measure.
unsafe
/// A buffer that reports a length no `u32` can express, without allocating one.
///
/// Every adapter checks the length and rejects the request before issuing any
/// native call, so this value is never owned by an operation and its pointer is
/// never dereferenced -- which is the only reason it can exist. The traits'
/// validity promise binds while an operation holds the buffer, and no operation
/// ever holds this one.
pub ;
// SAFETY: see the type's documentation -- the promise is never relied upon,
// because every path that would rely on it rejects this length first.
unsafe
// SAFETY: as above.
unsafe