Lines Matching refs:stream

35 /* Maximum distance between any two stream's cycle in the same
36 priority queue. Imagine stream A's cycle is A, and stream B's
60 void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
65 nghttp2_pq_init(&stream->obq, stream_less, mem);
67 stream->stream_id = stream_id;
68 stream->flags = flags;
69 stream->state = initial_state;
70 stream->shut_flags = NGHTTP2_SHUT_NONE;
71 stream->stream_user_data = stream_user_data;
72 stream->item = NULL;
73 stream->remote_window_size = remote_initial_window_size;
74 stream->local_window_size = local_initial_window_size;
75 stream->recv_window_size = 0;
76 stream->consumed_size = 0;
77 stream->recv_reduction = 0;
78 stream->window_update_queued = 0;
80 stream->dep_prev = NULL;
81 stream->dep_next = NULL;
82 stream->sib_prev = NULL;
83 stream->sib_next = NULL;
85 stream->closed_prev = NULL;
86 stream->closed_next = NULL;
88 stream->weight = weight;
89 stream->sum_dep_weight = 0;
91 stream->http_flags = NGHTTP2_HTTP_FLAG_NONE;
92 stream->content_length = -1;
93 stream->recv_content_length = 0;
94 stream->status_code = -1;
96 stream->queued = 0;
97 stream->descendant_last_cycle = 0;
98 stream->cycle = 0;
99 stream->pending_penalty = 0;
100 stream->descendant_next_seq = 0;
101 stream->seq = 0;
102 stream->last_writelen = 0;
104 stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
107 void nghttp2_stream_free(nghttp2_stream *stream) {
108 nghttp2_pq_free(&stream->obq);
109 /* We don't free stream->item. If it is assigned to aob, then
114 void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) {
115 stream->shut_flags = (uint8_t)(stream->shut_flags | flag);
119 * Returns nonzero if |stream| is active. This function does not take
122 static int stream_active(nghttp2_stream *stream) {
123 return stream->item &&
124 (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0;
128 * Returns nonzero if |stream| or one of its descendants is active
130 static int stream_subtree_active(nghttp2_stream *stream) {
131 return stream_active(stream) || !nghttp2_pq_empty(&stream->obq);
135 * Returns next cycle for |stream|.
137 static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
140 penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
141 stream->pending_penalty;
143 stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
144 stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
147 static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
150 for (; dep_stream && !stream->queued;
151 stream = dep_stream, dep_stream = dep_stream->dep_prev) {
152 stream_next_cycle(stream, dep_stream->descendant_last_cycle);
153 stream->seq = dep_stream->descendant_next_seq++;
155 DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id,
156 stream->cycle);
158 DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
161 rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
165 stream->queued = 1;
172 * Removes |stream| from parent's obq. If removal of |stream| makes
176 static void stream_obq_remove(nghttp2_stream *stream) {
179 dep_stream = stream->dep_prev;
181 if (!stream->queued) {
185 for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
186 DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
189 nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
191 assert(stream->queued);
193 stream->queued = 0;
194 stream->cycle = 0;
195 stream->pending_penalty = 0;
196 stream->descendant_last_cycle = 0;
197 stream->last_writelen = 0;
206 * Moves |stream| from |src|'s obq to |dest|'s obq. Removal from
212 nghttp2_stream *stream) {
213 if (!stream->queued) {
217 DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
220 nghttp2_pq_remove(&src->obq, &stream->pq_entry);
221 stream->queued = 0;
223 return stream_obq_push(dest, stream);
226 void nghttp2_stream_reschedule(nghttp2_stream *stream) {
229 assert(stream->queued);
231 dep_stream = stream->dep_prev;
233 for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
234 nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
236 stream_next_cycle(stream, dep_stream->descendant_last_cycle);
237 stream->seq = dep_stream->descendant_next_seq++;
239 nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
241 DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
242 stream->cycle);
244 dep_stream->last_writelen = stream->last_writelen;
248 void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
254 if (stream->weight == weight) {
258 old_weight = stream->weight;
259 stream->weight = weight;
261 dep_stream = stream->dep_prev;
269 if (!stream->queued) {
273 nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
275 wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
277 /* Compute old stream->pending_penalty we used to calculate
278 stream->cycle */
279 stream->pending_penalty =
280 (uint32_t)((stream->pending_penalty + (uint32_t)old_weight -
284 last_cycle = stream->cycle -
285 (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight;
287 /* Now we have old stream->pending_penalty and new stream->weight in
289 stream_next_cycle(stream, last_cycle);
291 if (dep_stream->descendant_last_cycle - stream->cycle <=
293 stream->cycle = dep_stream->descendant_last_cycle;
296 /* Continue to use same stream->seq */
298 nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
300 DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
301 stream->cycle);
304 static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
305 for (; stream->sib_next; stream = stream->sib_next)
308 return stream;
311 int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
313 weight = stream->weight * weight / stream->sum_dep_weight;
320 static void ensure_inactive(nghttp2_stream *stream) {
323 if (stream->queued) {
324 fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream,
325 stream->stream_id);
329 if (stream_active(stream)) {
330 fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n",
331 stream, stream->stream_id);
335 if (!nghttp2_pq_empty(&stream->obq)) {
336 fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream,
337 stream->stream_id, nghttp2_pq_size(&stream->obq));
341 for (si = stream->dep_next; si; si = si->sib_next) {
346 static void check_queued(nghttp2_stream *stream) {
350 if (stream->queued) {
351 if (!stream_subtree_active(stream)) {
353 "stream(%p)=%d, stream->queued == 1, but "
354 "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n",
355 stream, stream->stream_id, stream_active(stream),
356 nghttp2_pq_size(&stream->obq));
359 if (!stream_active(stream)) {
361 for (si = stream->dep_next; si; si = si->sib_next) {
368 "stream(%p)=%d, stream->queued == 1, and "
370 stream, stream->stream_id);
375 for (si = stream->dep_next; si; si = si->sib_next) {
379 if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
381 "stream(%p) = %d, stream->queued == 0, but "
382 "stream_active(stream) == %d and "
383 "nghttp2_pq_size(&stream->obq) = %zu\n",
384 stream, stream->stream_id, stream_active(stream),
385 nghttp2_pq_size(&stream->obq));
388 for (si = stream->dep_next; si; si = si->sib_next) {
394 static void check_sum_dep(nghttp2_stream *stream) {
397 for (si = stream->dep_next; si; si = si->sib_next) {
400 if (n != stream->sum_dep_weight) {
401 fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream,
402 stream->stream_id, n, stream->sum_dep_weight);
405 for (si = stream->dep_next; si; si = si->sib_next) {
410 static void check_dep_prev(nghttp2_stream *stream) {
412 for (si = stream->dep_next; si; si = si->sib_next) {
413 if (si->dep_prev != stream) {
414 fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream);
424 static void validate_tree(nghttp2_stream *stream) {
427 if (!stream) {
431 for (; stream->dep_prev; stream = stream->dep_prev)
434 assert(stream->stream_id == 0);
435 assert(!stream->queued);
438 if (nghttp2_pq_empty(&stream->obq)) {
440 for (si = stream->dep_next; si; si = si->sib_next) {
444 for (si = stream->dep_next; si; si = si->sib_next) {
449 check_sum_dep(stream);
450 check_dep_prev(stream);
453 static void validate_tree(nghttp2_stream *stream) { (void)stream; }
456 static int stream_update_dep_on_attach_item(nghttp2_stream *stream) {
459 rv = stream_obq_push(stream->dep_prev, stream);
464 validate_tree(stream);
468 static void stream_update_dep_on_detach_item(nghttp2_stream *stream) {
469 if (nghttp2_pq_empty(&stream->obq)) {
470 stream_obq_remove(stream);
473 validate_tree(stream);
476 int nghttp2_stream_attach_item(nghttp2_stream *stream,
480 assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
481 assert(stream->item == NULL);
483 DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
485 stream->item = item;
487 if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
491 rv = stream_update_dep_on_attach_item(stream);
493 /* This may relave stream->queued == 1, but stream->item == NULL.
497 stream->item = NULL;
504 void nghttp2_stream_detach_item(nghttp2_stream *stream) {
505 DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item);
507 stream->item = NULL;
508 stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
510 if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
514 stream_update_dep_on_detach_item(stream);
517 void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
518 assert(stream->item);
520 DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id,
521 stream->item, flags);
523 stream->flags |= flags;
525 if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
529 stream_update_dep_on_detach_item(stream);
532 int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
533 assert(stream->item);
535 DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
536 stream->item, flags);
538 stream->flags = (uint8_t)(stream->flags & ~flags);
540 if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
544 if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
548 return stream_update_dep_on_attach_item(stream);
551 int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) {
552 return stream->item && (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
555 int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream) {
556 return stream->item &&
557 (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
574 nghttp2_stream *stream, int32_t new_initial_window_size,
576 return update_initial_window_size(&stream->remote_window_size,
582 nghttp2_stream *stream, int32_t new_initial_window_size,
584 return update_initial_window_size(&stream->local_window_size,
589 void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
590 stream->state = NGHTTP2_STREAM_OPENED;
591 stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
594 int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
596 for (; stream; stream = stream->dep_prev) {
597 if (stream == target) {
605 nghttp2_stream *stream) {
609 DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
610 dep_stream->stream_id, stream, stream->stream_id);
612 stream->sum_dep_weight = dep_stream->sum_dep_weight;
613 dep_stream->sum_dep_weight = stream->weight;
617 si->dep_prev = stream;
619 rv = stream_obq_move(stream, dep_stream, si);
626 if (stream_subtree_active(stream)) {
627 rv = stream_obq_push(dep_stream, stream);
633 stream->dep_next = dep_stream->dep_next;
636 dep_stream->dep_next = stream;
637 stream->dep_prev = dep_stream;
639 validate_tree(stream);
644 static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) {
645 for (; stream; stream = stream->sib_next) {
646 stream->dep_prev = dep;
650 static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
651 dep_stream->dep_next = stream;
652 if (stream) {
653 stream->dep_prev = dep_stream;
665 nghttp2_stream *stream) {
668 assert(stream->sib_prev == NULL);
672 link_sib(stream, sib_next);
674 link_dep(dep_stream, stream);
677 static void unlink_sib(nghttp2_stream *stream) {
680 prev = stream->sib_prev;
681 dep_next = stream->dep_next;
687 * prev--stream(--sib_next--...)
694 set_dep_prev(dep_next, stream->dep_prev);
696 if (stream->sib_next) {
697 link_sib(stream_last_sib(dep_next), stream->sib_next);
701 * prev--stream(--sib_next--...)
703 next = stream->sib_next;
713 static void unlink_dep(nghttp2_stream *stream) {
716 prev = stream->dep_prev;
717 dep_next = stream->dep_next;
725 * stream(--sib_next--...)
731 set_dep_prev(dep_next, stream->dep_prev);
733 if (stream->sib_next) {
734 link_sib(stream_last_sib(dep_next), stream->sib_next);
737 } else if (stream->sib_next) {
741 * stream--sib_next
743 next = stream->sib_next;
754 nghttp2_stream *stream) {
755 DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
756 dep_stream->stream_id, stream, stream->stream_id);
758 dep_stream->sum_dep_weight += stream->weight;
761 link_dep(dep_stream, stream);
763 insert_link_dep(dep_stream, stream);
766 validate_tree(stream);
769 int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
774 DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
776 /* Distribute weight of |stream| to direct descendants */
777 sum_dep_weight_delta = -stream->weight;
779 for (si = stream->dep_next; si; si = si->sib_next) {
780 si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight);
785 rv = stream_obq_move(stream->dep_prev, stream, si);
792 assert(stream->dep_prev);
794 dep_prev = stream->dep_prev;
798 if (stream->queued) {
799 stream_obq_remove(stream);
802 if (stream->sib_prev) {
803 unlink_sib(stream);
805 unlink_dep(stream);
808 stream->sum_dep_weight = 0;
810 stream->dep_prev = NULL;
811 stream->dep_next = NULL;
812 stream->sib_prev = NULL;
813 stream->sib_next = NULL;
821 nghttp2_stream *stream) {
827 DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
828 dep_stream, dep_stream->stream_id, stream, stream->stream_id);
830 stream->sum_dep_weight += dep_stream->sum_dep_weight;
831 dep_stream->sum_dep_weight = stream->weight;
836 link_dep(dep_stream, stream);
838 if (stream->dep_next) {
839 last_sib = stream_last_sib(stream->dep_next);
843 link_dep(stream, dep_next);
847 si->dep_prev = stream;
849 rv = stream_obq_move(stream, dep_stream, si);
856 link_dep(dep_stream, stream);
859 if (stream_subtree_active(stream)) {
860 rv = stream_obq_push(dep_stream, stream);
872 nghttp2_stream *stream) {
875 DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
876 dep_stream, dep_stream->stream_id, stream, stream->stream_id);
878 dep_stream->sum_dep_weight += stream->weight;
881 insert_link_dep(dep_stream, stream);
883 link_dep(dep_stream, stream);
886 if (stream_subtree_active(stream)) {
887 rv = stream_obq_push(dep_stream, stream);
898 void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
901 DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
902 stream->stream_id);
904 assert(stream->dep_prev);
906 dep_prev = stream->dep_prev;
908 if (stream->sib_prev) {
909 link_sib(stream->sib_prev, stream->sib_next);
911 next = stream->sib_next;
920 dep_prev->sum_dep_weight -= stream->weight;
922 if (stream->queued) {
923 stream_obq_remove(stream);
928 stream->sib_prev = NULL;
929 stream->sib_next = NULL;
930 stream->dep_prev = NULL;
933 int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) {
934 return stream->dep_prev || stream->dep_next || stream->sib_prev ||
935 stream->sib_next;
939 nghttp2_stream_next_outbound_item(nghttp2_stream *stream) {
944 if (stream_active(stream)) {
946 assure that new stream is scheduled based on it. */
947 for (si = stream; si->dep_prev; si = si->dep_prev) {
950 return stream->item;
952 ent = nghttp2_pq_top(&stream->obq);
956 stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
960 nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
961 if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
965 if (stream->flags & NGHTTP2_STREAM_FLAG_PUSH) {
966 if (stream->shut_flags & NGHTTP2_SHUT_RD) {
970 if (stream->shut_flags & NGHTTP2_SHUT_WR) {
975 if (stream->shut_flags & NGHTTP2_SHUT_RD) {
979 if (stream->shut_flags & NGHTTP2_SHUT_WR) {
983 if (stream->state == NGHTTP2_STREAM_IDLE) {
990 nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) {
991 return stream->dep_prev;
994 nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) {
995 return stream->sib_next;
998 nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) {
999 return stream->sib_prev;
1002 nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) {
1003 return stream->dep_next;
1006 int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) {
1007 return stream->weight;
1010 int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) {
1011 return stream->sum_dep_weight;
1014 int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {
1015 return stream->stream_id;