void nghttp2_stream_reschedule(nghttp2_stream *stream) { nghttp2_stream *dep_stream; assert(stream->queued); dep_stream = stream->dep_prev; for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { if (nghttp2_pq_size(&dep_stream->obq) == 1) { dep_stream->descendant_last_cycle = 0; stream->cycle = 0; } else { dep_stream->descendant_last_cycle = nghttp2_max(dep_stream->descendant_last_cycle, stream->cycle); stream->cycle = stream_next_cycle(stream, dep_stream->descendant_last_cycle); nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); } DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%ld\n", stream->stream_id, stream->cycle)); dep_stream->last_writelen = stream->last_writelen; } }
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) { nghttp2_stream *dep_stream; uint32_t last_cycle; int32_t old_weight; uint32_t wlen_penalty; if (stream->weight == weight) { return; } old_weight = stream->weight; stream->weight = weight; dep_stream = stream->dep_prev; if (!dep_stream) { return; } dep_stream->sum_dep_weight += weight - old_weight; if (!stream->queued) { return; } nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); wlen_penalty = (uint32_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT; /* Compute old stream->pending_penalty we used to calculate stream->cycle */ stream->pending_penalty = (uint32_t)((stream->pending_penalty + (uint32_t)old_weight - (wlen_penalty % (uint32_t)old_weight)) % (uint32_t)old_weight); last_cycle = stream->cycle - (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight; /* Now we have old stream->pending_penalty and new stream->weight in place */ stream_next_cycle(stream, last_cycle); if (stream->cycle < dep_stream->descendant_last_cycle && (dep_stream->descendant_last_cycle - stream->cycle) <= NGHTTP2_MAX_CYCLE_DISTANCE) { stream->cycle = dep_stream->descendant_last_cycle; } /* Continue to use same stream->seq */ nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id, stream->cycle); }
void nghttp2_stream_reschedule(nghttp2_stream *stream) { nghttp2_stream *dep_stream; assert(stream->queued); dep_stream = stream->dep_prev; for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); stream_next_cycle(stream, dep_stream->descendant_last_cycle); stream->seq = dep_stream->descendant_next_seq++; nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id, stream->cycle); dep_stream->last_writelen = stream->last_writelen; } }
static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) { int rv; for (; dep_stream && !stream->queued; stream = dep_stream, dep_stream = dep_stream->dep_prev) { stream->cycle = stream_next_cycle(stream, dep_stream->descendant_last_cycle); DEBUGF(fprintf(stderr, "stream: stream=%d obq push cycle=%ld\n", stream->stream_id, stream->cycle)); DEBUGF(fprintf(stderr, "stream: push stream %d to stream %d\n", stream->stream_id, dep_stream->stream_id)); rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); if (rv != 0) { return rv; } stream->queued = 1; } return 0; }