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:
parent
e596385fc0
commit
1dea4e154b
|
@ -48,7 +48,12 @@ typedef struct {
|
||||||
nghttp2_frame_category frame_cat;
|
nghttp2_frame_category frame_cat;
|
||||||
void *frame;
|
void *frame;
|
||||||
void *aux_data;
|
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;
|
int64_t seq;
|
||||||
} nghttp2_outbound_item;
|
} nghttp2_outbound_item;
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,8 @@ static int outbound_item_update_pri
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item->pri = stream->pri;
|
/* We only update initial priority */
|
||||||
|
item->inipri = stream->pri;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,10 +443,12 @@ void nghttp2_session_reprioritize_stream
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stream->pri = pri;
|
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_pq, update_stream_pri, stream);
|
||||||
nghttp2_pq_update(&session->ob_ss_pq, update_stream_pri, stream);
|
nghttp2_pq_update(&session->ob_ss_pq, update_stream_pri, stream);
|
||||||
if(stream->deferred_data) {
|
if(stream->deferred_data) {
|
||||||
stream->deferred_data->pri = pri;
|
stream->deferred_data->inipri = pri;
|
||||||
}
|
}
|
||||||
if(session->aob.item) {
|
if(session->aob.item) {
|
||||||
outbound_item_update_pri(session->aob.item, stream);
|
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++;
|
item->seq = session->next_seq++;
|
||||||
/* Set priority to the default value at the moment. */
|
/* Set priority to the default value at the moment. */
|
||||||
item->pri = NGHTTP2_PRI_DEFAULT;
|
item->pri = NGHTTP2_PRI_DEFAULT;
|
||||||
|
item->pri_decay = 1;
|
||||||
if(frame_cat == NGHTTP2_CAT_CTRL) {
|
if(frame_cat == NGHTTP2_CAT_CTRL) {
|
||||||
nghttp2_frame *frame = (nghttp2_frame*)abs_frame;
|
nghttp2_frame *frame = (nghttp2_frame*)abs_frame;
|
||||||
nghttp2_stream *stream = NULL;
|
nghttp2_stream *stream = NULL;
|
||||||
|
@ -546,6 +550,7 @@ int nghttp2_session_add_frame(nghttp2_session *session,
|
||||||
free(item);
|
free(item);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
item->inipri = item->pri;
|
||||||
return 0;
|
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.
|
* Called after a frame is sent.
|
||||||
*
|
*
|
||||||
|
@ -1563,6 +1585,7 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
} else {
|
} else {
|
||||||
nghttp2_outbound_item* next_item;
|
nghttp2_outbound_item* next_item;
|
||||||
next_item = nghttp2_session_get_next_ob_item(session);
|
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
|
/* If priority of this stream is higher or equal to other stream
|
||||||
waiting at the top of the queue, we continue to send this
|
waiting at the top of the queue, we continue to send this
|
||||||
data. */
|
data. */
|
||||||
|
|
|
@ -1869,13 +1869,13 @@ void test_nghttp2_session_reprioritize_stream(void)
|
||||||
nghttp2_session_reprioritize_stream(session, stream, 120);
|
nghttp2_session_reprioritize_stream(session, stream, 120);
|
||||||
|
|
||||||
CU_ASSERT(session->aob.item != NULL);
|
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(120 == stream->pri);
|
||||||
CU_ASSERT(5000 == nghttp2_session_get_stream(session, 1)->pri);
|
CU_ASSERT(5000 == nghttp2_session_get_stream(session, 1)->pri);
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
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(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);
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue