1pub mod buffered;
2pub mod identity;
3pub mod reservation;
4pub mod send;
5
6use std::io;
7
8use crate::{Bytes, ProvidedLease, ProvidedView, RetainBytes};
9use dope_core::driver::DriverRef;
10use dope_core::driver::ready::ReadyKey;
11use dope_core::driver::token::Token;
12use o3::buffer::{Borrowed, Retained};
13
14use self::send::{Plain, Prepared, SendStorage, Sent, Storage, Vectored};
15
16pub enum Reclaim {
17 OnSubmit,
18 OnComplete,
19}
20
21pub enum RecvChunk<'a, R> {
22 Borrowed(Bytes<Borrowed<'a>>),
24 Owned(R),
26}
27
28pub struct RecvTarget<'a> {
33 buffer: &'a mut Vec<u8>,
34 limit: usize,
35}
36
37impl<'a> RecvTarget<'a> {
38 pub fn new(buffer: &'a mut Vec<u8>) -> Self {
39 buffer.clear();
40 let limit = buffer.capacity();
41 Self { buffer, limit }
42 }
43
44 pub fn len(&self) -> usize {
45 self.buffer.len()
46 }
47
48 pub fn remaining(&self) -> usize {
49 self.limit - self.buffer.len()
50 }
51
52 pub fn write_prefix(&mut self, source: &[u8]) -> usize {
53 let amount = source.len().min(self.remaining());
54 self.buffer.extend_from_slice(&source[..amount]);
55 amount
56 }
57
58 #[doc(hidden)]
59 pub fn with_limit(&mut self, limit: usize, fill: impl FnOnce(&mut RecvTarget<'_>)) -> usize {
60 let initial = self.buffer.len();
61 let previous = self.limit;
62 self.limit = initial + limit.min(self.remaining());
63 fill(self);
64 self.limit = previous;
65 self.buffer.len() - initial
66 }
67}
68
69pub trait RecvCursor: Unpin {
72 fn remaining(&self) -> usize;
73
74 fn read_into(&mut self, target: &mut RecvTarget<'_>);
76
77 fn is_empty(&self) -> bool {
78 self.remaining() == 0
79 }
80}
81
82impl RecvCursor for Bytes<Retained> {
83 fn remaining(&self) -> usize {
84 self.len()
85 }
86
87 fn read_into(&mut self, target: &mut RecvTarget<'_>) {
88 let count = target.write_prefix(self.as_slice());
89 self.consume_prefix_up_to(count);
90 }
91}
92
93impl RecvCursor for ProvidedView<'_> {
94 fn remaining(&self) -> usize {
95 self.len()
96 }
97
98 fn read_into(&mut self, target: &mut RecvTarget<'_>) {
99 let count = target.write_prefix(self.as_slice());
100 self.advance(count);
101 }
102}
103
104#[must_use]
109pub struct RecvCredit<'d> {
110 driver: DriverRef<'d>,
111 ready: ReadyKey<'d>,
112 target: Token,
113}
114
115#[must_use]
119pub struct RecvCreditGuard<'d>(RecvCredit<'d>);
120
121impl<'d> RecvCredit<'d> {
122 pub(crate) fn new(driver: DriverRef<'d>, ready: ReadyKey<'d>, target: Token) -> Self {
123 Self {
124 driver,
125 ready,
126 target,
127 }
128 }
129
130 pub fn claim(self) -> Result<RecvCreditGuard<'d>, Self> {
131 if !self.driver.arm_recv_credit(self.ready, self.target) {
132 return Err(self);
133 }
134 Ok(RecvCreditGuard(self))
135 }
136}
137
138impl Drop for RecvCreditGuard<'_> {
139 fn drop(&mut self) {
140 self.0
141 .driver
142 .release_recv_credit(self.0.ready, self.0.target);
143 }
144}
145
146#[derive(Clone, Copy)]
147pub struct RuntimeLimits {
148 max_connections: usize,
149 max_retained_recv_chunks: usize,
150 max_recv_len: usize,
151 recv_credit: bool,
152}
153
154impl RuntimeLimits {
155 pub fn new(
156 max_connections: usize,
157 max_retained_recv_chunks: usize,
158 max_recv_len: usize,
159 ) -> Self {
160 Self {
161 max_connections,
162 max_retained_recv_chunks,
163 max_recv_len,
164 recv_credit: false,
165 }
166 }
167
168 #[doc(hidden)]
169 pub fn with_recv_credit(mut self) -> Self {
170 self.recv_credit = true;
171 self
172 }
173
174 pub fn max_connections(self) -> usize {
175 self.max_connections
176 }
177
178 pub fn max_retained_recv_chunks(self) -> usize {
179 self.max_retained_recv_chunks
180 }
181
182 pub fn max_recv_len(self) -> usize {
183 self.max_recv_len
184 }
185
186 pub fn recv_credit(self) -> bool {
187 self.recv_credit
188 }
189}
190
191pub trait Wire: 'static + Sized {
192 type Connection<'d>: 'd
194 where
195 Self: 'd;
196 type ConnectionStorage: 'static;
198 type InitConfig<'d>: 'd
199 where
200 Self: 'd;
201 type RuntimeContext<'d>: 'd
202 where
203 Self: 'd;
204 type Open<'a, 'd>: OpenReservation<Self::Connection<'d>, Self::SendStorage>
205 where
206 'd: 'a;
207 type Recv<'a>: RetainBytes + 'a;
208 type RecvBatch<'a>: ExactSizeIterator<Item = RecvChunk<'a, Self::Recv<'a>>>
209 where
210 Self: 'a;
211 type RetainedRecv<'d>: RecvCursor + 'd
212 where
213 Self: 'd;
214 type SendStorage: SendStorage;
215
216 const RECLAIM: Reclaim;
217
218 const RAW_RECV: bool = false;
219
220 const RECV_CREDIT: bool = false;
222
223 fn connection_storage(capacity: usize) -> io::Result<Self::ConnectionStorage>;
224
225 fn runtime_context<'d>(
226 limits: RuntimeLimits,
227 config: Self::InitConfig<'d>,
228 ) -> io::Result<Self::RuntimeContext<'d>>
229 where
230 Self: 'd;
231
232 fn prepare_open<'a, 'd>(
233 runtime: &'a mut Self::RuntimeContext<'d>,
234 ) -> Option<Self::Open<'a, 'd>>
235 where
236 'd: 'a;
237
238 fn holds_plain<'d>(_wire: &Self::Connection<'d>, _send: &Self::SendStorage) -> bool {
239 false
240 }
241
242 fn process_recv<'a, 'd>(
245 wire: &mut Self::Connection<'d>,
246 runtime: &mut Self::RuntimeContext<'d>,
247 bytes: &'a mut [u8],
248 ) -> Self::RecvBatch<'a>;
249
250 fn process_retained_recv<'a, 'd>(
254 wire: &mut Self::Connection<'d>,
255 runtime: &mut Self::RuntimeContext<'d>,
256 bytes: ProvidedLease<'a>,
257 ) -> Option<Self::RetainedRecv<'a>>;
258
259 fn bind_recv_credit<'d>(
266 recv: &mut Self::RetainedRecv<'d>,
267 credit: RecvCredit<'d>,
268 ) -> Result<(), RecvCredit<'d>> {
269 let _ = recv;
270 Err(credit)
271 }
272
273 fn recv_eof<'d>(_wire: &mut Self::Connection<'d>) {}
274
275 fn prepare_send<'a, 'd>(
276 wire: &'a mut Self::Connection<'d>,
277 send: Storage<'a, Self::SendStorage>,
278 plain: Plain<'a>,
279 ) -> Prepared<'a>;
280
281 fn prepare_send_vectored<'a, 'd>(
282 wire: &'a mut Self::Connection<'d>,
283 send: Storage<'a, Self::SendStorage>,
284 plain: Vectored<'a>,
285 ) -> Prepared<'a>;
286
287 fn submit_failed<'d>(_wire: &mut Self::Connection<'d>) {}
288
289 fn after_send<'a, 'd>(
290 wire: &'a mut Self::Connection<'d>,
291 send: Storage<'a, Self::SendStorage>,
292 sent: Sent,
293 ) -> Prepared<'a>;
294
295 fn flush_pending<'a, 'd>(
296 wire: &'a mut Self::Connection<'d>,
297 send: Storage<'a, Self::SendStorage>,
298 ) -> Prepared<'a>;
299
300 fn graceful_close<'a, 'd>(
301 _wire: &'a mut Self::Connection<'d>,
302 send: Storage<'a, Self::SendStorage>,
303 ) -> Prepared<'a> {
304 send.empty(0)
305 }
306}
307
308pub trait OpenReservation<W, S> {
309 fn commit(self) -> (W, S);
310}
311
312pub trait OpenRollback<W, S> {
313 fn rollback_open(&mut self, open: (W, S));
314}
315
316pub struct ReadyOpen<W, S> {
317 committed: (W, S),
318}
319
320impl<W, S> ReadyOpen<W, S> {
321 pub fn new(wire: W, send: S) -> Self {
322 Self {
323 committed: (wire, send),
324 }
325 }
326}
327
328impl<W, S> OpenReservation<W, S> for ReadyOpen<W, S> {
329 fn commit(self) -> (W, S) {
330 self.committed
331 }
332}