1use crate::Reason;
2
3use super::*;
4
5use std::fmt;
6use std::task::{Context, Waker};
7use std::time::Instant;
8
9pub(super) struct Stream {
21 pub id: StreamId,
23
24 pub state: State,
26
27 pub is_counted: bool,
30
31 pub ref_count: usize,
33
34 pub next_pending_send: Option<store::Key>,
37
38 pub is_pending_send: bool,
40
41 pub send_flow: FlowControl,
43
44 pub requested_send_capacity: WindowSize,
46
47 pub buffered_send_data: usize,
50
51 send_task: Option<Waker>,
53
54 pub pending_send: buffer::Deque,
56
57 pub next_pending_send_capacity: Option<store::Key>,
60
61 pub is_pending_send_capacity: bool,
63
64 pub send_capacity_inc: bool,
66
67 pub next_open: Option<store::Key>,
69
70 pub is_pending_open: bool,
72
73 pub is_pending_push: bool,
75
76 pub next_pending_accept: Option<store::Key>,
79
80 pub is_pending_accept: bool,
82
83 pub recv_flow: FlowControl,
85
86 pub in_flight_recv_data: WindowSize,
87
88 pub next_window_update: Option<store::Key>,
90
91 pub is_pending_window_update: bool,
93
94 pub reset_at: Option<Instant>,
96
97 pub next_reset_expire: Option<store::Key>,
99
100 pub pending_recv: buffer::Deque,
102
103 pub is_recv: bool,
105
106 pub recv_task: Option<Waker>,
108
109 pub push_task: Option<Waker>,
111
112 pub pending_push_promises: store::Queue<NextAccept>,
114
115 pub content_length: ContentLength,
117}
118
119#[derive(Debug)]
121pub enum ContentLength {
122 Omitted,
123 Head,
124 Remaining(u64),
125}
126
127#[derive(Debug)]
128pub(super) struct NextAccept;
129
130#[derive(Debug)]
131pub(super) struct NextSend;
132
133#[derive(Debug)]
134pub(super) struct NextSendCapacity;
135
136#[derive(Debug)]
137pub(super) struct NextWindowUpdate;
138
139#[derive(Debug)]
140pub(super) struct NextOpen;
141
142#[derive(Debug)]
143pub(super) struct NextResetExpire;
144
145impl Stream {
146 pub fn new(id: StreamId, init_send_window: WindowSize, init_recv_window: WindowSize) -> Stream {
147 let mut send_flow = FlowControl::new();
148 let mut recv_flow = FlowControl::new();
149
150 recv_flow
151 .inc_window(init_recv_window)
152 .expect("invalid initial receive window");
153 let _res = recv_flow.assign_capacity(init_recv_window);
155 debug_assert!(_res.is_ok());
156
157 send_flow
158 .inc_window(init_send_window)
159 .expect("invalid initial send window size");
160
161 Stream {
162 id,
163 state: State::default(),
164 ref_count: 0,
165 is_counted: false,
166
167 next_pending_send: None,
169 is_pending_send: false,
170 send_flow,
171 requested_send_capacity: 0,
172 buffered_send_data: 0,
173 send_task: None,
174 pending_send: buffer::Deque::new(),
175 is_pending_send_capacity: false,
176 next_pending_send_capacity: None,
177 send_capacity_inc: false,
178 is_pending_open: false,
179 next_open: None,
180 is_pending_push: false,
181
182 next_pending_accept: None,
184 is_pending_accept: false,
185 recv_flow,
186 in_flight_recv_data: 0,
187 next_window_update: None,
188 is_pending_window_update: false,
189 reset_at: None,
190 next_reset_expire: None,
191 pending_recv: buffer::Deque::new(),
192 is_recv: true,
193 recv_task: None,
194 push_task: None,
195 pending_push_promises: store::Queue::new(),
196 content_length: ContentLength::Omitted,
197 }
198 }
199
200 pub fn ref_inc(&mut self) {
202 assert!(self.ref_count < usize::MAX);
203 self.ref_count += 1;
204 }
205
206 pub fn ref_dec(&mut self) {
208 assert!(self.ref_count > 0);
209 self.ref_count -= 1;
210 }
211
212 pub fn is_pending_reset_expiration(&self) -> bool {
215 self.reset_at.is_some()
216 }
217
218 pub fn is_send_ready(&self) -> bool {
220 !self.is_pending_open && !self.is_pending_push
236 }
237
238 pub fn is_closed(&self) -> bool {
240 self.state.is_closed() &&
242 self.pending_send.is_empty() &&
245 self.buffered_send_data == 0
251 }
252
253 pub fn is_released(&self) -> bool {
255 self.is_closed() &&
257 self.ref_count == 0 &&
259 !self.is_pending_send && !self.is_pending_send_capacity &&
261 !self.is_pending_accept && !self.is_pending_window_update &&
262 !self.is_pending_open && self.reset_at.is_none()
263 }
264
265 pub fn is_canceled_interest(&self) -> bool {
271 self.ref_count == 0 && !self.state.is_closed()
272 }
273
274 pub fn capacity(&self, max_buffer_size: usize) -> WindowSize {
276 let available = self.send_flow.available().as_size() as usize;
277 let buffered = self.buffered_send_data;
278
279 available.min(max_buffer_size).saturating_sub(buffered) as WindowSize
280 }
281
282 pub fn assign_capacity(&mut self, capacity: WindowSize, max_buffer_size: usize) {
283 let prev_capacity = self.capacity(max_buffer_size);
284 debug_assert!(capacity > 0);
285 let _res = self.send_flow.assign_capacity(capacity);
287 debug_assert!(_res.is_ok());
288
289 tracing::trace!(
290 " assigned capacity to stream; available={}; buffered={}; id={:?}; max_buffer_size={} prev={}",
291 self.send_flow.available(),
292 self.buffered_send_data,
293 self.id,
294 max_buffer_size,
295 prev_capacity,
296 );
297
298 if prev_capacity < self.capacity(max_buffer_size) {
299 self.notify_capacity();
300 }
301 }
302
303 pub fn send_data(&mut self, len: WindowSize, max_buffer_size: usize) {
304 let prev_capacity = self.capacity(max_buffer_size);
305
306 let _res = self.send_flow.send_data(len);
308 debug_assert!(_res.is_ok());
309
310 debug_assert!(self.buffered_send_data >= len as usize);
312 self.buffered_send_data -= len as usize;
313 self.requested_send_capacity -= len;
314
315 tracing::trace!(
316 " sent stream data; available={}; buffered={}; id={:?}; max_buffer_size={} prev={}",
317 self.send_flow.available(),
318 self.buffered_send_data,
319 self.id,
320 max_buffer_size,
321 prev_capacity,
322 );
323
324 if prev_capacity < self.capacity(max_buffer_size) {
325 self.notify_capacity();
326 }
327 }
328
329 pub fn notify_capacity(&mut self) {
332 self.send_capacity_inc = true;
333 tracing::trace!(" notifying task");
334 self.notify_send();
335 }
336
337 pub fn dec_content_length(&mut self, len: usize) -> Result<(), ()> {
339 match self.content_length {
340 ContentLength::Remaining(ref mut rem) => match rem.checked_sub(len as u64) {
341 Some(val) => *rem = val,
342 None => return Err(()),
343 },
344 ContentLength::Head if len != 0 => {
345 return Err(());
346 }
347 _ => {}
348 }
349
350 Ok(())
351 }
352
353 pub fn ensure_content_length_zero(&self) -> Result<(), ()> {
354 match self.content_length {
355 ContentLength::Remaining(0) => Ok(()),
356 ContentLength::Remaining(_) => Err(()),
357 _ => Ok(()),
358 }
359 }
360
361 pub fn notify_send(&mut self) {
362 if let Some(task) = self.send_task.take() {
363 task.wake();
364 }
365 }
366
367 pub fn wait_send(&mut self, cx: &Context) {
368 self.send_task = Some(cx.waker().clone());
369 }
370
371 pub fn notify_recv(&mut self) {
372 if let Some(task) = self.recv_task.take() {
373 task.wake();
374 }
375 }
376
377 pub(super) fn notify_push(&mut self) {
378 if let Some(task) = self.push_task.take() {
379 task.wake();
380 }
381 }
382
383 pub(super) fn set_reset(&mut self, reason: Reason, initiator: Initiator) {
386 self.state.set_reset(self.id, reason, initiator);
387 self.notify_send();
388 self.notify_push();
389 self.notify_recv();
390 }
391}
392
393impl fmt::Debug for Stream {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 f.debug_struct("Stream")
396 .field("id", &self.id)
397 .field("state", &self.state)
398 .field("is_counted", &self.is_counted)
399 .field("ref_count", &self.ref_count)
400 .h2_field_some("next_pending_send", &self.next_pending_send)
401 .h2_field_if("is_pending_send", &self.is_pending_send)
402 .field("send_flow", &self.send_flow)
403 .field("requested_send_capacity", &self.requested_send_capacity)
404 .field("buffered_send_data", &self.buffered_send_data)
405 .h2_field_some("send_task", &self.send_task.as_ref().map(|_| ()))
406 .h2_field_if_then(
407 "pending_send",
408 !self.pending_send.is_empty(),
409 &self.pending_send,
410 )
411 .h2_field_some(
412 "next_pending_send_capacity",
413 &self.next_pending_send_capacity,
414 )
415 .h2_field_if("is_pending_send_capacity", &self.is_pending_send_capacity)
416 .h2_field_if("send_capacity_inc", &self.send_capacity_inc)
417 .h2_field_some("next_open", &self.next_open)
418 .h2_field_if("is_pending_open", &self.is_pending_open)
419 .h2_field_if("is_pending_push", &self.is_pending_push)
420 .h2_field_some("next_pending_accept", &self.next_pending_accept)
421 .h2_field_if("is_pending_accept", &self.is_pending_accept)
422 .field("recv_flow", &self.recv_flow)
423 .field("in_flight_recv_data", &self.in_flight_recv_data)
424 .h2_field_some("next_window_update", &self.next_window_update)
425 .h2_field_if("is_pending_window_update", &self.is_pending_window_update)
426 .h2_field_some("reset_at", &self.reset_at)
427 .h2_field_some("next_reset_expire", &self.next_reset_expire)
428 .h2_field_if_then(
429 "pending_recv",
430 !self.pending_recv.is_empty(),
431 &self.pending_recv,
432 )
433 .h2_field_if("is_recv", &self.is_recv)
434 .h2_field_some("recv_task", &self.recv_task.as_ref().map(|_| ()))
435 .h2_field_some("push_task", &self.push_task.as_ref().map(|_| ()))
436 .h2_field_if_then(
437 "pending_push_promises",
438 !self.pending_push_promises.is_empty(),
439 &self.pending_push_promises,
440 )
441 .field("content_length", &self.content_length)
442 .finish()
443 }
444}
445
446impl store::Next for NextAccept {
447 fn next(stream: &Stream) -> Option<store::Key> {
448 stream.next_pending_accept
449 }
450
451 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
452 stream.next_pending_accept = key;
453 }
454
455 fn take_next(stream: &mut Stream) -> Option<store::Key> {
456 stream.next_pending_accept.take()
457 }
458
459 fn is_queued(stream: &Stream) -> bool {
460 stream.is_pending_accept
461 }
462
463 fn set_queued(stream: &mut Stream, val: bool) {
464 stream.is_pending_accept = val;
465 }
466}
467
468impl store::Next for NextSend {
469 fn next(stream: &Stream) -> Option<store::Key> {
470 stream.next_pending_send
471 }
472
473 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
474 stream.next_pending_send = key;
475 }
476
477 fn take_next(stream: &mut Stream) -> Option<store::Key> {
478 stream.next_pending_send.take()
479 }
480
481 fn is_queued(stream: &Stream) -> bool {
482 stream.is_pending_send
483 }
484
485 fn set_queued(stream: &mut Stream, val: bool) {
486 if val {
487 debug_assert!(!stream.is_pending_open);
490 }
491 stream.is_pending_send = val;
492 }
493}
494
495impl store::Next for NextSendCapacity {
496 fn next(stream: &Stream) -> Option<store::Key> {
497 stream.next_pending_send_capacity
498 }
499
500 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
501 stream.next_pending_send_capacity = key;
502 }
503
504 fn take_next(stream: &mut Stream) -> Option<store::Key> {
505 stream.next_pending_send_capacity.take()
506 }
507
508 fn is_queued(stream: &Stream) -> bool {
509 stream.is_pending_send_capacity
510 }
511
512 fn set_queued(stream: &mut Stream, val: bool) {
513 stream.is_pending_send_capacity = val;
514 }
515}
516
517impl store::Next for NextWindowUpdate {
518 fn next(stream: &Stream) -> Option<store::Key> {
519 stream.next_window_update
520 }
521
522 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
523 stream.next_window_update = key;
524 }
525
526 fn take_next(stream: &mut Stream) -> Option<store::Key> {
527 stream.next_window_update.take()
528 }
529
530 fn is_queued(stream: &Stream) -> bool {
531 stream.is_pending_window_update
532 }
533
534 fn set_queued(stream: &mut Stream, val: bool) {
535 stream.is_pending_window_update = val;
536 }
537}
538
539impl store::Next for NextOpen {
540 fn next(stream: &Stream) -> Option<store::Key> {
541 stream.next_open
542 }
543
544 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
545 stream.next_open = key;
546 }
547
548 fn take_next(stream: &mut Stream) -> Option<store::Key> {
549 stream.next_open.take()
550 }
551
552 fn is_queued(stream: &Stream) -> bool {
553 stream.is_pending_open
554 }
555
556 fn set_queued(stream: &mut Stream, val: bool) {
557 if val {
558 debug_assert!(!stream.is_pending_send);
561 }
562 stream.is_pending_open = val;
563 }
564}
565
566impl store::Next for NextResetExpire {
567 fn next(stream: &Stream) -> Option<store::Key> {
568 stream.next_reset_expire
569 }
570
571 fn set_next(stream: &mut Stream, key: Option<store::Key>) {
572 stream.next_reset_expire = key;
573 }
574
575 fn take_next(stream: &mut Stream) -> Option<store::Key> {
576 stream.next_reset_expire.take()
577 }
578
579 fn is_queued(stream: &Stream) -> bool {
580 stream.reset_at.is_some()
581 }
582
583 fn set_queued(stream: &mut Stream, val: bool) {
584 if val {
585 stream.reset_at = Some(Instant::now());
586 } else {
587 stream.reset_at = None;
588 }
589 }
590}
591
592impl ContentLength {
595 pub fn is_head(&self) -> bool {
596 matches!(*self, Self::Head)
597 }
598}