int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream) { int rv; DEBUGF(fprintf(stderr, "stream: dep_add_subtree dep_stream(%p)=%d " "stream(%p)=%d\n", dep_stream, dep_stream->stream_id, stream, stream->stream_id)); dep_stream->sum_dep_weight += stream->weight; if (dep_stream->dep_next) { insert_link_dep(dep_stream, stream); } else { link_dep(dep_stream, stream); } if (stream_subtree_active(stream)) { rv = stream_obq_push(dep_stream, stream); if (rv != 0) { return rv; } } validate_tree(dep_stream); return 0; }
/* * Removes |stream| from parent's obq. If removal of |stream| makes * parent's obq empty, and parent is not active, then parent is also * removed. This process is repeated recursively. */ static void stream_obq_remove(nghttp2_stream *stream) { nghttp2_stream *dep_stream; dep_stream = stream->dep_prev; if (!stream->queued) { return; } for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d\n", stream->stream_id, dep_stream->stream_id)); nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); assert(stream->queued); stream->queued = 0; stream->cycle = 0; stream->descendant_last_cycle = 0; if (stream_subtree_active(dep_stream)) { return; } } }
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream) { nghttp2_stream *last_sib; nghttp2_stream *dep_next; nghttp2_stream *si; int rv; DEBUGF(fprintf(stderr, "stream: dep_insert_subtree dep_stream(%p)=%d " "stream(%p)=%d\n", dep_stream, dep_stream->stream_id, stream, stream->stream_id)); stream->sum_dep_weight += dep_stream->sum_dep_weight; dep_stream->sum_dep_weight = stream->weight; if (dep_stream->dep_next) { dep_next = dep_stream->dep_next; link_dep(dep_stream, stream); if (stream->dep_next) { last_sib = stream_last_sib(stream->dep_next); link_sib(last_sib, dep_next); } else { link_dep(stream, dep_next); } for (si = dep_next; si; si = si->sib_next) { si->dep_prev = stream; if (si->queued) { rv = stream_obq_move(stream, dep_stream, si); if (rv != 0) { return rv; } } } } else { link_dep(dep_stream, stream); } if (stream_subtree_active(stream)) { rv = stream_obq_push(dep_stream, stream); if (rv != 0) { return rv; } } validate_tree(dep_stream); return 0; }
static void check_queued(nghttp2_stream *stream) { nghttp2_stream *si; int queued; if (stream->queued) { if (!stream_subtree_active(stream)) { fprintf(stderr, "stream(%p)=%d, stream->queued == 1, but " "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n", stream, stream->stream_id, stream_active(stream), nghttp2_pq_size(&stream->obq)); assert(0); } if (!stream_active(stream)) { queued = 0; for (si = stream->dep_next; si; si = si->sib_next) { if (si->queued) { ++queued; } } if (queued == 0) { fprintf(stderr, "stream(%p)=%d, stream->queued == 1, and " "!stream_active(), but no descendants is queued\n", stream, stream->stream_id); assert(0); } } for (si = stream->dep_next; si; si = si->sib_next) { check_queued(si); } } else { if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) { fprintf(stderr, "stream(%p) = %d, stream->queued == 0, but " "stream_active(stream) == %d and " "nghttp2_pq_size(&stream->obq) = %zu\n", stream, stream->stream_id, stream_active(stream), nghttp2_pq_size(&stream->obq)); assert(0); } for (si = stream->dep_next; si; si = si->sib_next) { ensure_inactive(si); } } }
int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream, nghttp2_stream *stream) { nghttp2_stream *si; int rv; DEBUGF(fprintf(stderr, "stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream, dep_stream->stream_id, stream, stream->stream_id)); stream->sum_dep_weight = dep_stream->sum_dep_weight; dep_stream->sum_dep_weight = stream->weight; if (dep_stream->dep_next) { for (si = dep_stream->dep_next; si; si = si->sib_next) { si->dep_prev = stream; if (si->queued) { rv = stream_obq_move(stream, dep_stream, si); if (rv != 0) { return rv; } } } if (stream_subtree_active(stream)) { rv = stream_obq_push(dep_stream, stream); if (rv != 0) { return rv; } } stream->dep_next = dep_stream->dep_next; } dep_stream->dep_next = stream; stream->dep_prev = dep_stream; validate_tree(stream); return 0; }