Reintroduce priority adjustment for DATA frame

This mechanism existed but was deleted. We bring it back in order to
prevent lower priority streams from starving.
This commit is contained in:
Tatsuhiro Tsujikawa 2013-12-05 23:12:18 +09:00
parent e596385fc0
commit 1dea4e154b
3 changed files with 34 additions and 6 deletions

View File

@ -48,7 +48,12 @@ typedef struct {
nghttp2_frame_category frame_cat;
void *frame;
void *aux_data;
int pri;
/* The priority used in priority comparion */
int32_t pri;
/* The initial priority */
int32_t inipri;
/* The amount of priority decrement in next time */
uint32_t pri_decay;
int64_t seq;
} nghttp2_outbound_item;

View File

@ -424,7 +424,8 @@ static int outbound_item_update_pri
return 0;
}
}
item->pri = stream->pri;
/* We only update initial priority */
item->inipri = stream->pri;
return 1;
}
@ -442,10 +443,12 @@ void nghttp2_session_reprioritize_stream
return;
}
stream->pri = pri;
/* For submitted frames, we only update initial priority, so the
structure of the queue will remain unchanged. */
nghttp2_pq_update(&session->ob_pq, update_stream_pri, stream);
nghttp2_pq_update(&session->ob_ss_pq, update_stream_pri, stream);
if(stream->deferred_data) {
stream->deferred_data->pri = pri;
stream->deferred_data->inipri = pri;
}
if(session->aob.item) {
outbound_item_update_pri(session->aob.item, stream);
@ -471,6 +474,7 @@ int nghttp2_session_add_frame(nghttp2_session *session,
item->seq = session->next_seq++;
/* Set priority to the default value at the moment. */
item->pri = NGHTTP2_PRI_DEFAULT;
item->pri_decay = 1;
if(frame_cat == NGHTTP2_CAT_CTRL) {
nghttp2_frame *frame = (nghttp2_frame*)abs_frame;
nghttp2_stream *stream = NULL;
@ -546,6 +550,7 @@ int nghttp2_session_add_frame(nghttp2_session *session,
free(item);
return r;
}
item->inipri = item->pri;
return 0;
}
@ -1385,6 +1390,23 @@ nghttp2_outbound_item* nghttp2_session_pop_next_ob_item
}
}
/*
* Adjust priority of the |item|. In order to prevent the low priority
* streams from starving, lower the priority of the |item| by
* item->pri_decay. If the resulting priority exceeds
* NGHTTP2_PRI_DEFAULT, back to the original priority.
*/
static void adjust_pri(nghttp2_outbound_item *item)
{
if(item->pri >= (int32_t)(NGHTTP2_PRI_LOWEST - (item->pri_decay - 1))) {
item->pri = item->inipri;
item->pri_decay = 1;
return;
}
item->pri += (int32_t)(item->pri_decay - 1);
item->pri_decay <<= 1;
}
/*
* Called after a frame is sent.
*
@ -1563,6 +1585,7 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
} else {
nghttp2_outbound_item* next_item;
next_item = nghttp2_session_get_next_ob_item(session);
adjust_pri(session->aob.item);
/* If priority of this stream is higher or equal to other stream
waiting at the top of the queue, we continue to send this
data. */

View File

@ -1869,13 +1869,13 @@ void test_nghttp2_session_reprioritize_stream(void)
nghttp2_session_reprioritize_stream(session, stream, 120);
CU_ASSERT(session->aob.item != NULL);
CU_ASSERT(120 == session->aob.item->pri);
CU_ASSERT(120 == session->aob.item->inipri);
CU_ASSERT(120 == stream->pri);
CU_ASSERT(5000 == nghttp2_session_get_stream(session, 1)->pri);
item = nghttp2_session_get_next_ob_item(session);
CU_ASSERT(120 == item->pri);
CU_ASSERT(5000 == item->inipri);
CU_ASSERT(NGHTTP2_HEADERS == OB_CTRL_TYPE(item));
CU_ASSERT(3 == OB_CTRL(item)->hd.stream_id);
CU_ASSERT(1 == OB_CTRL(item)->hd.stream_id);
nghttp2_session_del(session);