1use std::{cell::Cell, fmt, io, task::Poll};
2
3use ntex_bytes::{BytePageSize, BytePages, BytesMut};
4
5use crate::{IoConfig, IoRef};
6
7pub(crate) struct Stack {
8 buffers: Vec<Buffer>,
9}
10
11#[derive(Default)]
12struct Buffer {
13 read: Cell<Option<BytesMut>>,
14 write: Cell<Option<BytePages>>,
15}
16
17impl fmt::Debug for Stack {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 f.debug_struct("Stack")
20 .field("len", &self.buffers.len())
21 .finish()
22 }
23}
24
25impl Stack {
26 pub(crate) fn new(size: BytePageSize) -> Self {
27 Self {
28 buffers: vec![
29 Buffer {
30 read: Cell::new(None),
31 write: Cell::new(Some(BytePages::new(size))),
32 },
33 Buffer {
34 read: Cell::new(None),
35 write: Cell::new(Some(BytePages::new(size))),
36 },
37 ],
38 }
39 }
40
41 pub(crate) fn set_page_size(&self, size: BytePageSize) {
42 for b in &self.buffers {
43 b.with_write(|b| b.set_page_size(size));
44 }
45 }
46
47 pub(crate) fn add_layer(&mut self, page_size: BytePageSize) {
48 self.buffers.insert(
49 0,
50 Buffer {
51 read: Cell::new(None),
52 write: Cell::new(Some(BytePages::new(page_size))),
53 },
54 );
55 }
56
57 fn with_last<F, R>(&self, f: F) -> R
58 where
59 F: FnOnce(&Buffer) -> R,
60 {
61 f(&self.buffers[self.buffers.len() - 2])
62 }
63
64 pub(crate) fn with_read_src<F, R>(&self, io: &IoRef, f: F) -> R
65 where
66 F: FnOnce(&mut BytesMut) -> R,
67 {
68 self.with_last(|buf| buf.with_read(io, f))
69 }
70
71 pub(crate) fn with_read_dst<F, R>(&self, io: &IoRef, f: F) -> R
72 where
73 F: FnOnce(&mut BytesMut) -> R,
74 {
75 self.buffers[0].with_read(io, f)
76 }
77
78 pub(crate) fn write_buf_size(&self) -> usize {
79 if self.buffers.len() == 2 {
81 self.buffers[0].write_len()
82 } else {
83 self.buffers[0].write_len() + self.buffers[self.buffers.len() - 2].write_len()
84 }
85 }
86
87 pub(crate) fn with_write_src<F, R>(&self, f: F) -> R
88 where
89 F: FnOnce(&mut BytePages) -> R,
90 {
91 self.buffers[0].with_write(f)
92 }
93
94 pub(crate) fn with_write_dst<F, R>(&self, f: F) -> R
95 where
96 F: FnOnce(&mut BytePages) -> R,
97 {
98 self.buffers[self.buffers.len() - 2].with_write(f)
99 }
100
101 pub(crate) fn read_dst_size(&self) -> usize {
102 self.buffers[0].read_len()
103 }
104
105 pub(crate) fn with_filter<F, R>(&self, io: &IoRef, f: F) -> R
106 where
107 F: FnOnce(&mut FilterCtx<'_>) -> R,
108 {
109 let mut ctx = FilterCtx {
110 io,
111 idx: 0,
112 nbytes: 0,
113 stack: self,
114 st: FilterUpdates {
115 wants_write: false,
116 notify: false,
117 },
118 };
119 f(&mut ctx)
120 }
121
122 pub(crate) fn get_read_buf(&self) -> Option<BytesMut> {
123 self.with_last(|buffer| buffer.read.take())
124 }
125
126 pub(crate) fn set_read_buf(&self, buf: BytesMut, cfg: &IoConfig) {
127 self.with_last(move |buffer| {
128 if let Some(mut first_buf) = buffer.read.take() {
129 first_buf.extend_from_slice(&buf);
130 cfg.read_buf().release(buf);
131 buffer.read.set(Some(first_buf));
132 } else if !buf.is_empty() {
133 buffer.read.set(Some(buf));
134 } else {
135 cfg.read_buf().release(buf);
136 }
137 });
138 }
139
140 pub(crate) fn process_read_buf(
141 &self,
142 io: &IoRef,
143 nbytes: usize,
144 ) -> io::Result<FilterUpdates> {
145 let mut ctx = FilterCtx {
146 io,
147 nbytes,
148 idx: 0,
149 stack: self,
150 st: FilterUpdates {
151 wants_write: false,
152 notify: false,
153 },
154 };
155 io.with_callbacks(|cb| cb.before_processing(io));
156 let result = io.filter().process_read_buf(&mut ctx);
157 io.with_callbacks(|cb| cb.after_processing(io));
158
159 result.map(|()| ctx.st)
160 }
161
162 pub(crate) fn process_read_buf_no_cb(
163 &self,
164 io: &IoRef,
165 nbytes: usize,
166 ) -> io::Result<FilterUpdates> {
167 let mut ctx = FilterCtx {
168 io,
169 nbytes,
170 idx: 0,
171 stack: self,
172 st: FilterUpdates {
173 wants_write: false,
174 notify: false,
175 },
176 };
177 io.filter().process_read_buf(&mut ctx).map(|()| ctx.st)
178 }
179
180 pub(crate) fn process_write_buf(&self, io: &IoRef) -> io::Result<()> {
181 if self.buffers[0].is_write_empty() {
182 Ok(())
183 } else {
184 let mut ctx = FilterCtx {
185 io,
186 idx: 0,
187 nbytes: 0,
188 stack: self,
189 st: FilterUpdates {
190 wants_write: true,
191 notify: false,
192 },
193 };
194 io.with_callbacks(|cb| cb.before_processing(io));
195 let res = io.filter().process_write_buf(&mut ctx);
196 io.with_callbacks(|cb| cb.after_processing(io));
197
198 res
199 }
200 }
201
202 pub(crate) fn process_write_buf_no_cb(&self, io: &IoRef) -> io::Result<()> {
203 if self.buffers[0].is_write_empty() {
204 Ok(())
205 } else {
206 let mut ctx = FilterCtx {
207 io,
208 idx: 0,
209 nbytes: 0,
210 stack: self,
211 st: FilterUpdates {
212 wants_write: true,
213 notify: false,
214 },
215 };
216 io.filter().process_write_buf(&mut ctx)
217 }
218 }
219
220 pub(crate) fn process_write_buf_force(&self, io: &IoRef) -> io::Result<()> {
221 let mut ctx = FilterCtx {
222 io,
223 idx: 0,
224 nbytes: 0,
225 stack: self,
226 st: FilterUpdates {
227 wants_write: true,
228 notify: false,
229 },
230 };
231 io.with_callbacks(|cb| cb.before_processing(io));
232 let res = io.filter().process_write_buf(&mut ctx);
233 io.with_callbacks(|cb| cb.after_processing(io));
234
235 res
236 }
237
238 pub(crate) fn process_shutdown(&self, io: &IoRef) -> io::Result<Poll<()>> {
239 self.process_write_buf(io)?;
240 io.with_callbacks(|cb| cb.before_processing(io));
241 let res = self.with_filter(io, |ctx| io.filter().shutdown(ctx));
242 io.with_callbacks(|cb| cb.after_processing(io));
243
244 res
245 }
246}
247
248impl Buffer {
249 fn is_write_empty(&self) -> bool {
250 self.with_write(|b| b.is_empty())
251 }
252
253 fn read_len(&self) -> usize {
254 if let Some(rb) = self.read.take() {
255 let l = rb.len();
256 self.read.set(Some(rb));
257 l
258 } else {
259 0
260 }
261 }
262
263 fn write_len(&self) -> usize {
264 self.with_write(|b| b.len())
265 }
266
267 fn with_read<F, R>(&self, io: &IoRef, f: F) -> R
268 where
269 F: FnOnce(&mut BytesMut) -> R,
270 {
271 let mut rb = self
272 .read
273 .take()
274 .unwrap_or_else(|| io.cfg().read_buf().get());
275 let result = f(&mut rb);
276
277 if self.read.take().is_some() {
279 log::error!("Nested read io operation is detected");
280 io.terminate();
281 }
282
283 if rb.is_empty() {
284 io.cfg().read_buf().release(rb);
285 } else {
286 self.read.set(Some(rb));
287 }
288 result
289 }
290
291 fn with_write<F, R>(&self, f: F) -> R
292 where
293 F: FnOnce(&mut BytePages) -> R,
294 {
295 let mut wb = self.write.take().unwrap();
296 let result = f(&mut wb);
297 self.write.set(Some(wb));
298 result
299 }
300}
301
302#[derive(Copy, Clone, Debug)]
303pub(crate) struct FilterUpdates {
304 pub(crate) wants_write: bool,
305 pub(crate) notify: bool,
306}
307
308#[derive(Debug)]
309pub struct FilterCtx<'a> {
310 io: &'a IoRef,
311 idx: usize,
312 nbytes: usize,
313 stack: &'a Stack,
314 st: FilterUpdates,
315}
316
317impl FilterCtx<'_> {
318 #[inline]
319 pub fn io(&self) -> &IoRef {
321 self.io
322 }
323
324 #[inline]
325 pub fn tag(&self) -> &'static str {
327 self.io.tag()
328 }
329
330 #[inline]
331 pub fn new_read_bytes(&self) -> usize {
333 self.nbytes
334 }
335
336 #[inline]
337 pub fn notify(&mut self) {
339 self.st.notify = true;
340 }
341
342 #[inline]
343 pub fn with_next<F, R>(&mut self, f: F) -> R
345 where
346 F: FnOnce(&mut Self) -> R,
347 {
348 self.idx += 1;
349 let res = f(self);
350 self.idx -= 1;
351 res
352 }
353
354 #[inline]
355 pub fn with_buffer<F, R>(&mut self, f: F) -> R
357 where
358 F: FnOnce(&mut FilterBuf<'_>) -> R,
359 {
360 let mut buf = FilterBuf {
361 io: self.io,
362 curr: &self.stack.buffers[self.idx],
363 next: &self.stack.buffers[self.idx + 1],
364 wants_write: Cell::new(self.st.wants_write),
365 };
366 let result = f(&mut buf);
367 if buf.wants_write.get() {
368 self.st.wants_write = true;
369 }
370 result
371 }
372
373 #[inline]
374 pub fn read_dst_size(&self) -> usize {
376 self.stack.buffers[0].read_len()
377 }
378
379 #[inline]
380 pub fn write_dst_size(&mut self) -> usize {
382 self.stack.buffers[self.stack.buffers.len() - 2].write_len()
383 }
384
385 pub(crate) fn clear_write_buf(&mut self) {
386 self.stack.buffers[self.idx].with_write(BytePages::clear);
387 }
388}
389
390#[derive(Debug)]
391pub struct FilterBuf<'a> {
392 io: &'a IoRef,
393 curr: &'a Buffer,
394 next: &'a Buffer,
395 wants_write: Cell<bool>,
396}
397
398impl FilterBuf<'_> {
399 #[inline]
400 pub fn io(&self) -> &IoRef {
402 self.io
403 }
404
405 #[inline]
406 pub fn tag(&self) -> &'static str {
408 self.io.tag()
409 }
410
411 pub fn with_read_src<F, R>(&self, f: F) -> R
413 where
414 F: FnOnce(&mut Option<BytesMut>) -> R,
415 {
416 let mut read_src = self.next.read.take();
417 let result = f(&mut read_src);
418
419 if let Some(b) = read_src {
420 if b.is_empty() {
421 self.io.cfg().read_buf().release(b);
422 } else {
423 self.next.read.set(Some(b));
424 }
425 }
426 result
427 }
428
429 pub fn with_read_buffers<F, R>(&self, f: F) -> R
431 where
432 F: FnOnce(&mut Option<BytesMut>, &mut BytesMut) -> R,
433 {
434 let mut read_src = self.next.read.take();
435 let mut read_dst = self
436 .curr
437 .read
438 .take()
439 .unwrap_or_else(|| self.io.cfg().read_buf().get());
440
441 let result = f(&mut read_src, &mut read_dst);
442
443 if let Some(b) = read_src {
444 if b.is_empty() {
445 self.io.cfg().read_buf().release(b);
446 } else {
447 self.next.read.set(Some(b));
448 }
449 }
450 if read_dst.is_empty() {
451 self.io.cfg().read_buf().release(read_dst);
452 } else {
453 self.curr.read.set(Some(read_dst));
454 }
455
456 result
457 }
458
459 #[inline]
460 pub fn with_write_buffers<F, R>(&self, f: F) -> R
462 where
463 F: FnOnce(&mut BytePages, &mut BytePages) -> R,
464 {
465 let mut write_curr = self.curr.write.take().unwrap();
466 let mut write_next = self.next.write.take().unwrap();
467 let write_len = if self.wants_write.get() {
468 0
469 } else {
470 write_next.len()
471 };
472
473 let result = f(&mut write_curr, &mut write_next);
474
475 if !self.wants_write.get() && write_next.len() > write_len {
476 self.wants_write.set(true);
477 }
478
479 self.curr.write.set(Some(write_curr));
480 self.next.write.set(Some(write_next));
481 result
482 }
483}
484
485impl fmt::Debug for Buffer {
486 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
487 let read = self.read.take();
488 let write = self.write.take();
489
490 let result = f
491 .debug_struct("Buffer")
492 .field("read", &read)
493 .field("write", &write)
494 .finish();
495 self.read.set(read);
496 self.write.set(write);
497 result
498 }
499}