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(&self, io: &IoRef, nbytes: usize) -> io::Result<FilterUpdates> {
141 let mut ctx = FilterCtx {
142 io,
143 nbytes,
144 idx: 0,
145 stack: self,
146 st: FilterUpdates {
147 wants_write: false,
148 notify: false,
149 },
150 };
151 io.with_callbacks(|cb| cb.before_processing(io));
152 let result = io.filter().process_read_buf(&mut ctx);
153 io.with_callbacks(|cb| cb.after_processing(io));
154
155 result.map(|()| ctx.st)
156 }
157
158 pub(crate) fn process_read_buf_no_cb(
159 &self,
160 io: &IoRef,
161 nbytes: usize,
162 ) -> io::Result<FilterUpdates> {
163 let mut ctx = FilterCtx {
164 io,
165 nbytes,
166 idx: 0,
167 stack: self,
168 st: FilterUpdates {
169 wants_write: false,
170 notify: false,
171 },
172 };
173 io.filter().process_read_buf(&mut ctx).map(|()| ctx.st)
174 }
175
176 pub(crate) fn process_write_buf(&self, io: &IoRef) -> io::Result<()> {
177 if self.buffers[0].is_write_empty() {
178 Ok(())
179 } else {
180 let mut ctx = FilterCtx {
181 io,
182 idx: 0,
183 nbytes: 0,
184 stack: self,
185 st: FilterUpdates {
186 wants_write: true,
187 notify: false,
188 },
189 };
190 io.with_callbacks(|cb| cb.before_processing(io));
191 let res = io.filter().process_write_buf(&mut ctx);
192 io.with_callbacks(|cb| cb.after_processing(io));
193
194 res
195 }
196 }
197
198 pub(crate) fn process_write_buf_no_cb(&self, io: &IoRef) -> io::Result<()> {
199 if self.buffers[0].is_write_empty() {
200 Ok(())
201 } else {
202 let mut ctx = FilterCtx {
203 io,
204 idx: 0,
205 nbytes: 0,
206 stack: self,
207 st: FilterUpdates {
208 wants_write: true,
209 notify: false,
210 },
211 };
212 io.filter().process_write_buf(&mut ctx)
213 }
214 }
215
216 pub(crate) fn process_write_buf_force(&self, io: &IoRef) -> io::Result<()> {
217 let mut ctx = FilterCtx {
218 io,
219 idx: 0,
220 nbytes: 0,
221 stack: self,
222 st: FilterUpdates {
223 wants_write: true,
224 notify: false,
225 },
226 };
227 io.with_callbacks(|cb| cb.before_processing(io));
228 let res = io.filter().process_write_buf(&mut ctx);
229 io.with_callbacks(|cb| cb.after_processing(io));
230
231 res
232 }
233
234 pub(crate) fn process_shutdown(&self, io: &IoRef) -> io::Result<Poll<()>> {
235 self.process_write_buf(io)?;
236 io.with_callbacks(|cb| cb.before_processing(io));
237 let res = self.with_filter(io, |ctx| io.filter().shutdown(ctx));
238 io.with_callbacks(|cb| cb.after_processing(io));
239
240 res
241 }
242}
243
244impl Buffer {
245 fn is_write_empty(&self) -> bool {
246 self.with_write(|b| b.is_empty())
247 }
248
249 fn read_len(&self) -> usize {
250 if let Some(rb) = self.read.take() {
251 let l = rb.len();
252 self.read.set(Some(rb));
253 l
254 } else {
255 0
256 }
257 }
258
259 fn write_len(&self) -> usize {
260 self.with_write(|b| b.len())
261 }
262
263 fn with_read<F, R>(&self, io: &IoRef, f: F) -> R
264 where
265 F: FnOnce(&mut BytesMut) -> R,
266 {
267 let mut rb = self
268 .read
269 .take()
270 .unwrap_or_else(|| io.cfg().read_buf().get());
271 let result = f(&mut rb);
272
273 if self.read.take().is_some() {
275 log::error!("Nested read io operation is detected");
276 io.terminate();
277 }
278
279 if rb.is_empty() {
280 io.cfg().read_buf().release(rb);
281 } else {
282 self.read.set(Some(rb));
283 }
284 result
285 }
286
287 fn with_write<F, R>(&self, f: F) -> R
288 where
289 F: FnOnce(&mut BytePages) -> R,
290 {
291 let mut wb = self.write.take().unwrap();
292 let result = f(&mut wb);
293 self.write.set(Some(wb));
294 result
295 }
296}
297
298#[derive(Copy, Clone, Debug)]
299pub(crate) struct FilterUpdates {
300 pub(crate) wants_write: bool,
301 pub(crate) notify: bool,
302}
303
304#[derive(Debug)]
305pub struct FilterCtx<'a> {
306 io: &'a IoRef,
307 idx: usize,
308 nbytes: usize,
309 stack: &'a Stack,
310 st: FilterUpdates,
311}
312
313impl FilterCtx<'_> {
314 #[inline]
315 pub fn io(&self) -> &IoRef {
317 self.io
318 }
319
320 #[inline]
321 pub fn tag(&self) -> &'static str {
323 self.io.tag()
324 }
325
326 #[inline]
327 pub fn new_read_bytes(&self) -> usize {
329 self.nbytes
330 }
331
332 #[inline]
333 pub fn notify(&mut self) {
335 self.st.notify = true;
336 }
337
338 #[inline]
339 pub fn with_next<F, R>(&mut self, f: F) -> R
341 where
342 F: FnOnce(&mut Self) -> R,
343 {
344 self.idx += 1;
345 let res = f(self);
346 self.idx -= 1;
347 res
348 }
349
350 #[inline]
351 pub fn with_buffer<F, R>(&mut self, f: F) -> R
353 where
354 F: FnOnce(&mut FilterBuf<'_>) -> R,
355 {
356 let mut buf = FilterBuf {
357 io: self.io,
358 curr: &self.stack.buffers[self.idx],
359 next: &self.stack.buffers[self.idx + 1],
360 wants_write: Cell::new(self.st.wants_write),
361 };
362 let result = f(&mut buf);
363 if buf.wants_write.get() {
364 self.st.wants_write = true;
365 }
366 result
367 }
368
369 #[inline]
370 pub fn read_dst_size(&self) -> usize {
372 self.stack.buffers[0].read_len()
373 }
374
375 #[inline]
376 pub fn write_dst_size(&mut self) -> usize {
378 self.stack.buffers[self.stack.buffers.len() - 2].write_len()
379 }
380
381 pub(crate) fn clear_write_buf(&mut self) {
382 self.stack.buffers[self.idx].with_write(BytePages::clear);
383 }
384}
385
386#[derive(Debug)]
387pub struct FilterBuf<'a> {
388 io: &'a IoRef,
389 curr: &'a Buffer,
390 next: &'a Buffer,
391 wants_write: Cell<bool>,
392}
393
394impl FilterBuf<'_> {
395 #[inline]
396 pub fn io(&self) -> &IoRef {
398 self.io
399 }
400
401 #[inline]
402 pub fn tag(&self) -> &'static str {
404 self.io.tag()
405 }
406
407 pub fn with_read_src<F, R>(&self, f: F) -> R
409 where
410 F: FnOnce(&mut Option<BytesMut>) -> R,
411 {
412 let mut read_src = self.next.read.take();
413 let result = f(&mut read_src);
414
415 if let Some(b) = read_src {
416 if b.is_empty() {
417 self.io.cfg().read_buf().release(b);
418 } else {
419 self.next.read.set(Some(b));
420 }
421 }
422 result
423 }
424
425 pub fn with_read_buffers<F, R>(&self, f: F) -> R
427 where
428 F: FnOnce(&mut Option<BytesMut>, &mut BytesMut) -> R,
429 {
430 let mut read_src = self.next.read.take();
431 let mut read_dst = self
432 .curr
433 .read
434 .take()
435 .unwrap_or_else(|| self.io.cfg().read_buf().get());
436
437 let result = f(&mut read_src, &mut read_dst);
438
439 if let Some(b) = read_src {
440 if b.is_empty() {
441 self.io.cfg().read_buf().release(b);
442 } else {
443 self.next.read.set(Some(b));
444 }
445 }
446 if read_dst.is_empty() {
447 self.io.cfg().read_buf().release(read_dst);
448 } else {
449 self.curr.read.set(Some(read_dst));
450 }
451
452 result
453 }
454
455 #[inline]
456 pub fn with_write_buffers<F, R>(&self, f: F) -> R
458 where
459 F: FnOnce(&mut BytePages, &mut BytePages) -> R,
460 {
461 let mut write_curr = self.curr.write.take().unwrap();
462 let mut write_next = self.next.write.take().unwrap();
463 let write_len = if self.wants_write.get() {
464 0
465 } else {
466 write_next.len()
467 };
468
469 let result = f(&mut write_curr, &mut write_next);
470
471 if !self.wants_write.get() && write_next.len() > write_len {
472 self.wants_write.set(true);
473 }
474
475 self.curr.write.set(Some(write_curr));
476 self.next.write.set(Some(write_next));
477 result
478 }
479}
480
481impl fmt::Debug for Buffer {
482 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
483 let read = self.read.take();
484 let write = self.write.take();
485
486 let result = f
487 .debug_struct("Buffer")
488 .field("read", &read)
489 .field("write", &write)
490 .finish();
491 self.read.set(read);
492 self.write.set(write);
493 result
494 }
495}