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
// Copyright (c) 2026 Mike Grier
//! Owned buffers an operation (or a buffer registration) can hold.
//!
//! Duplicated from `windows-overlapped-io-sys`'s `IoBuf`/`IoBufMut` (D-1 in
//! `DESIGN-NOTES.md`): the reasoning below is identical, because it is about
//! memory and address stability, not about which completion mechanism reads
//! or writes through the pointer. The two crates share no code; see D-1 for
//! why, and M6+ for when that might change.
//!
//! # The contract is extended to cover registration (M2.1)
//!
//! `windows-overlapped-io-sys`'s version of this contract binds "for as long
//! as the value is owned by an operation." Here it binds for as long as this
//! crate holds the value at all, because that span is no longer always one
//! operation: `BuildIoRingRegisterBuffers` (M5) registers a buffer once and
//! reuses it, by index, across many later reads and writes. A buffer held by
//! a live registration must stay exactly as stable and valid as one held by
//! a single in-flight operation -- the kernel can address it through
//! either path -- so the promise below is phrased in terms of "this crate
//! holds it," not "an operation holds it."
//!
//! # Why owned, and not a slice
//!
//! Completion-based I/O touches the caller's memory *after* the submitting
//! call returns. A `&[u8]` cannot describe that: its borrow would have to
//! span the whole operation, and nothing in the API can make it: the ring has
//! no `Drop` that cancels an operation, and even one would be defeated by
//! `mem::forget`, so a caller could always end the borrow with the kernel
//! still reading. The buffer is handed over instead, and the pop that observes
//! its completion is what hands it back ([`crate::IoRing::try_pop`]).
//!
//! # 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 held, 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).
///
/// # Safety
///
/// Implementors guarantee that, for as long as this crate holds the value --
/// whether as a single operation's payload, or as a buffer
/// registration spanning many operations (M5) -- :
///
/// - [`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 a completion may be observed on a different thread from
/// the one that submitted the operation; `'static` because a registered or
/// in-flight buffer carries no lifetime this crate can check.
pub unsafe
/// An owned buffer an operation writes bytes **into** (a read).
///
/// 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.
///
/// # 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.
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