diff --git a/lib/nghttp2_outbound_item.h b/lib/nghttp2_outbound_item.h index 00500cf1..55597b85 100644 --- a/lib/nghttp2_outbound_item.h +++ b/lib/nghttp2_outbound_item.h @@ -56,12 +56,13 @@ typedef struct { inipri. The item is chosen from the queue based on pri and seq. For control frames, they consist of just 1 frame and pri does not change. For DATA frame, they could split up to several - frames. After sending a frame, the pri is increased by 1. If it - becomes more than lowest priority, then it returns back to inipri - and do the same sequence again and again. By doing this, the - higher priority long DATA frames don't starve the lower - prioritized streams. */ + frames. After sending a frame, the pri becomes |inipri| + + |pridecay| and |pridecay| is multiplied by 2. If it becomes more + than lowest priority, then it returns back to |inipri| and do the + same sequence again and again. By doing this, the higher priority + long DATA frames don't starve the lower prioritized streams. */ int pri; + uint32_t pridecay; int64_t seq; } nghttp2_outbound_item; diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 81a43aa4..487c8350 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -388,6 +388,7 @@ int nghttp2_session_add_frame(nghttp2_session *session, return r; } item->inipri = item->pri; + item->pridecay = 1; return 0; } @@ -979,12 +980,19 @@ nghttp2_outbound_item* nghttp2_session_pop_next_ob_item static void nghttp2_outbound_item_adjust_pri(nghttp2_session *session, nghttp2_outbound_item *item) { + assert(item->pri > 0); if(item->pri == NGHTTP2_PRI_LOWEST) { - item->pri = item->inipri; - } else if(item->pri > (int32_t)NGHTTP2_PRI_LOWEST/2) { + nghttp2_stream *stream; + stream = nghttp2_session_get_stream + (session, nghttp2_outbound_item_get_data_frame(item)->hd.stream_id); + assert(stream); + item->pri = item->inipri = stream->pri; + item->pridecay = 1; + } else if(item->pri + item->pridecay > NGHTTP2_PRI_LOWEST) { item->pri = NGHTTP2_PRI_LOWEST; } else { - item->pri *= 2; + item->pri = item->inipri + item->pridecay; + item->pridecay *= 2; } }