Interleave stream DATA more naturally

We simulate resource sharing by decreasing weight.  The thing is if
weight is wrapped, that item continues to send DATA until its weight
gets lowered under the other items.  This commits fix this issue.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-05-08 23:07:29 +09:00
parent b041218a2a
commit 3e3d51842b
6 changed files with 150 additions and 87 deletions

View File

@ -46,6 +46,9 @@ typedef struct {
typedef struct {
int64_t seq;
/* Reset count of weight. See comment for last_cycle in
nghttp2_session.h */
uint64_t cycle;
void *frame;
void *aux_data;
/* Type of |frame|. NGHTTP2_CTRL: nghttp2_frame*, NGHTTP2_DATA:

View File

@ -154,12 +154,16 @@ static int nghttp2_outbound_item_compar(const void *lhsx, const void *rhsx)
lhs = (const nghttp2_outbound_item*)lhsx;
rhs = (const nghttp2_outbound_item*)rhsx;
if(lhs->weight == rhs->weight) {
return (lhs->seq < rhs->seq) ? -1 : ((lhs->seq > rhs->seq) ? 1 : 0);
if(lhs->cycle == rhs->cycle) {
if(lhs->weight == rhs->weight) {
return (lhs->seq < rhs->seq) ? -1 : ((lhs->seq > rhs->seq) ? 1 : 0);
}
/* Larger weight has higher precedence */
return rhs->weight - lhs->weight;
}
/* Larger weight has higher precedence */
return rhs->weight - lhs->weight;
return (lhs->cycle < rhs->cycle) ? -1 : 1;
}
static void nghttp2_inbound_frame_reset(nghttp2_session *session)
@ -287,6 +291,7 @@ static int nghttp2_session_new(nghttp2_session **session_ptr,
nghttp2_stream_roots_init(&(*session_ptr)->roots);
(*session_ptr)->next_seq = 0;
(*session_ptr)->last_cycle = 1;
(*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
(*session_ptr)->recv_window_size = 0;
@ -482,9 +487,10 @@ int nghttp2_session_reprioritize_stream
session->roots.num_streams <= NGHTTP2_MAX_DEP_TREE_LENGTH) {
rv = nghttp2_stream_dep_all_your_stream_are_belong_to_us
(stream, &session->ob_pq);
(stream, &session->ob_pq, session->last_cycle);
} else {
rv = nghttp2_stream_dep_make_root(stream, &session->ob_pq);
rv = nghttp2_stream_dep_make_root(stream, &session->ob_pq,
session->last_cycle);
}
return rv;
@ -504,7 +510,8 @@ int nghttp2_session_reprioritize_stream
stream, stream->stream_id));
nghttp2_stream_dep_remove_subtree(dep_stream);
nghttp2_stream_dep_make_root(dep_stream, &session->ob_pq);
nghttp2_stream_dep_make_root(dep_stream, &session->ob_pq,
session->last_cycle);
}
nghttp2_stream_dep_remove_subtree(stream);
@ -516,14 +523,17 @@ int nghttp2_session_reprioritize_stream
if(root_stream->num_substreams + stream->num_substreams >
NGHTTP2_MAX_DEP_TREE_LENGTH) {
rv = nghttp2_stream_dep_make_root(stream, &session->ob_pq);
rv = nghttp2_stream_dep_make_root(stream, &session->ob_pq,
session->last_cycle);
} else {
if(pri_spec->exclusive) {
rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream,
&session->ob_pq);
&session->ob_pq,
session->last_cycle);
} else {
rv = nghttp2_stream_dep_add_subtree(dep_stream, stream,
&session->ob_pq);
&session->ob_pq,
session->last_cycle);
}
}
@ -553,6 +563,8 @@ int nghttp2_session_add_frame(nghttp2_session *session,
item->frame = abs_frame;
item->aux_data = aux_data;
item->seq = session->next_seq++;
/* We use cycle for DATA only */
item->cycle = 0;
item->weight = NGHTTP2_OB_EX_WEIGHT;
item->queued = 0;
@ -630,8 +642,10 @@ int nghttp2_session_add_frame(nghttp2_session *session,
rv = NGHTTP2_ERR_DATA_EXIST;
} else {
item->weight = stream->effective_weight;
item->cycle = session->last_cycle;
rv = nghttp2_stream_attach_data(stream, item, &session->ob_pq);
rv = nghttp2_stream_attach_data(stream, item, &session->ob_pq,
session->last_cycle);
}
}
@ -740,7 +754,7 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
if(pri_spec->exclusive &&
session->roots.num_streams <= NGHTTP2_MAX_DEP_TREE_LENGTH) {
rv = nghttp2_stream_dep_all_your_stream_are_belong_to_us
(stream, &session->ob_pq);
(stream, &session->ob_pq, session->last_cycle);
/* Since no dpri is changed in dependency tree, the above
function call never fail. */
@ -796,7 +810,8 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
item = stream->data_item;
rv = nghttp2_stream_detach_data(stream, &session->ob_pq);
rv = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);
if(rv != 0) {
return rv;
@ -1755,7 +1770,8 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
int rv2;
if(stream) {
rv2 = nghttp2_stream_detach_data(stream, &session->ob_pq);
rv2 = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv2)) {
return rv2;
@ -1777,7 +1793,7 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
rv = nghttp2_stream_defer_data(stream,
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
&session->ob_pq);
&session->ob_pq, session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -1793,7 +1809,7 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
data_frame);
if(framerv == NGHTTP2_ERR_DEFERRED) {
rv = nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER,
&session->ob_pq);
&session->ob_pq, session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -1804,7 +1820,8 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_DEFERRED;
}
if(framerv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_stream_detach_data(stream, &session->ob_pq);
rv = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -1949,11 +1966,19 @@ static int session_call_on_frame_send(nghttp2_session *session,
return 0;
}
static void outbound_item_cycle_weight(nghttp2_outbound_item *item,
int32_t ini_weight)
static void session_outbound_item_cycle_weight(nghttp2_session *session,
nghttp2_outbound_item *item,
int32_t ini_weight)
{
if(item->weight == NGHTTP2_MIN_WEIGHT || item->weight > ini_weight) {
item->weight = ini_weight;
if(item->cycle == session->last_cycle) {
item->cycle = ++session->last_cycle;
} else {
item->cycle = session->last_cycle;
}
} else {
--item->weight;
}
@ -2144,7 +2169,8 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
}
if(stream && data_frame->eof) {
rv = nghttp2_stream_detach_data(stream, &session->ob_pq);
rv = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -2176,13 +2202,15 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
assert(stream);
next_item = nghttp2_session_get_next_ob_item(session);
outbound_item_cycle_weight(aob->item, stream->effective_weight);
session_outbound_item_cycle_weight(session, aob->item,
stream->effective_weight);
/* 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. */
if(stream->dpri == NGHTTP2_STREAM_DPRI_TOP &&
(next_item == NULL || aob->item->weight > next_item->weight)) {
(next_item == NULL ||
nghttp2_outbound_item_compar(item, next_item) < 0)) {
size_t next_readmax;
next_readmax = nghttp2_session_next_data_read(session, stream);
@ -2195,7 +2223,8 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
}
rv = nghttp2_stream_defer_data
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_pq);
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -2217,7 +2246,7 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
if(rv == NGHTTP2_ERR_DEFERRED) {
rv = nghttp2_stream_defer_data(stream,
NGHTTP2_STREAM_FLAG_DEFERRED_USER,
&session->ob_pq);
&session->ob_pq, session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -2240,7 +2269,8 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
return rv;
}
rv = nghttp2_stream_detach_data(stream, &session->ob_pq);
rv = nghttp2_stream_detach_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -2254,9 +2284,6 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
return 0;
}
/* Update seq to interleave other streams with the same
priority. */
aob->item->seq = session->next_seq++;
if(stream->dpri == NGHTTP2_STREAM_DPRI_TOP) {
rv = nghttp2_pq_push(&session->ob_pq, aob->item);
@ -3183,7 +3210,8 @@ static int nghttp2_update_remote_initial_window_size_func
stream->remote_window_size > 0 &&
arg->session->remote_window_size > 0) {
rv = nghttp2_stream_resume_deferred_data(stream, &arg->session->ob_pq);
rv = nghttp2_stream_resume_deferred_data(stream, &arg->session->ob_pq,
arg->session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -3701,7 +3729,8 @@ static int nghttp2_push_back_deferred_data_func(nghttp2_map_entry *entry,
if(nghttp2_stream_check_deferred_by_flow_control(stream) &&
stream->remote_window_size > 0) {
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq);
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -3778,7 +3807,8 @@ static int session_on_stream_window_update_received
session->remote_window_size > 0 &&
nghttp2_stream_check_deferred_by_flow_control(stream)) {
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq);
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;
@ -5624,7 +5654,8 @@ int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id)
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq);
rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_pq,
session->last_cycle);
if(nghttp2_is_fatal(rv)) {
return rv;

View File

@ -130,6 +130,20 @@ struct nghttp2_session {
/* Sequence number of outbound frame to maintain the order of
enqueue if priority is equal. */
int64_t next_seq;
/* Reset count of nghttp2_outbound_item's weight. We decrements
weight each time DATA is sent to simulate resource sharing. We
use priority queue and larger weight has the precedence. If
weight is reached to lowest weight, it resets to its initial
weight. If this happens, other items which have the lower weight
currently but same initial weight cannot send DATA until item
having large weight is decreased. To avoid this, we use this
cycle variable. Initally, this is set to 1. If weight gets
lowest weight, and if item's cycle == last_cycle, we increments
last_cycle and assigns it to item's cycle. Otherwise, just
assign last_cycle. In priority queue comparator, we first
compare items' cycle value. Lower cycle value has the
precedence. */
uint64_t last_cycle;
void *user_data;
/* Points to the latest closed stream. NULL if there is no closed
stream. Only used when session is initialized as server. */

View File

@ -85,7 +85,8 @@ void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag)
stream->shut_flags |= flag;
}
static int stream_push_data(nghttp2_stream *stream, nghttp2_pq *pq)
static int stream_push_data(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle)
{
int rv;
@ -96,6 +97,8 @@ static int stream_push_data(nghttp2_stream *stream, nghttp2_pq *pq)
stream->data_item->weight = stream->effective_weight;
}
stream->data_item->cycle = cycle;
rv = nghttp2_pq_push(pq, stream->data_item);
if(rv != 0) {
@ -216,7 +219,8 @@ static void stream_update_dep_set_rest(nghttp2_stream *stream)
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq)
static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle)
{
int rv;
nghttp2_stream *si;
@ -230,7 +234,7 @@ static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq)
stream->stream_id));
if(!stream->data_item->queued) {
rv = stream_push_data(stream, pq);
rv = stream_push_data(stream, pq, cycle);
if(rv != 0) {
return rv;
@ -243,7 +247,7 @@ static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq)
}
for(si = stream->dep_next; si; si = si->sib_next) {
rv = stream_update_dep_set_top(si, pq);
rv = stream_update_dep_set_top(si, pq, cycle);
if(rv != 0) {
return rv;
@ -292,7 +296,7 @@ static int stream_update_dep_sum_norest_weight(nghttp2_stream *stream)
}
static int stream_update_dep_on_attach_data(nghttp2_stream *stream,
nghttp2_pq *pq)
nghttp2_pq *pq, uint64_t cycle)
{
int rv;
nghttp2_stream *root_stream;
@ -305,7 +309,7 @@ static int stream_update_dep_on_attach_data(nghttp2_stream *stream,
DEBUGF(fprintf(stderr, "root=%p, stream=%p\n", root_stream, stream));
rv = stream_update_dep_set_top(root_stream, pq);
rv = stream_update_dep_set_top(root_stream, pq, cycle);
if(rv != 0) {
return rv;
@ -318,7 +322,7 @@ static int stream_update_dep_on_attach_data(nghttp2_stream *stream,
}
static int stream_update_dep_on_detach_data(nghttp2_stream *stream,
nghttp2_pq *pq)
nghttp2_pq *pq, uint64_t cycle)
{
int rv;
nghttp2_stream *root_stream;
@ -327,7 +331,7 @@ static int stream_update_dep_on_detach_data(nghttp2_stream *stream,
root_stream = nghttp2_stream_get_dep_root(stream);
rv = stream_update_dep_set_top(root_stream, pq);
rv = stream_update_dep_set_top(root_stream, pq, cycle);
if(rv != 0) {
return rv;
@ -341,7 +345,8 @@ static int stream_update_dep_on_detach_data(nghttp2_stream *stream,
int nghttp2_stream_attach_data(nghttp2_stream *stream,
nghttp2_outbound_item *data_item,
nghttp2_pq *pq)
nghttp2_pq *pq,
uint64_t cycle)
{
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
assert(stream->data_item == NULL);
@ -351,10 +356,11 @@ int nghttp2_stream_attach_data(nghttp2_stream *stream,
stream->data_item = data_item;
return stream_update_dep_on_attach_data(stream, pq);
return stream_update_dep_on_attach_data(stream, pq, cycle);
}
int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq)
int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle)
{
DEBUGF(fprintf(stderr, "stream: stream=%d detach data=%p\n",
stream->stream_id, stream->data_item));
@ -362,11 +368,11 @@ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq)
stream->data_item = NULL;
stream->flags &= ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL;
return stream_update_dep_on_detach_data(stream, pq);
return stream_update_dep_on_detach_data(stream, pq, cycle);
}
int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
nghttp2_pq *pq)
nghttp2_pq *pq, uint64_t cycle)
{
assert(stream->data_item);
@ -375,11 +381,11 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
stream->flags |= flags;
return stream_update_dep_on_detach_data(stream, pq);
return stream_update_dep_on_detach_data(stream, pq, cycle);
}
int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream,
nghttp2_pq *pq)
nghttp2_pq *pq, uint64_t cycle)
{
assert(stream->data_item);
@ -388,7 +394,7 @@ int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream,
stream->flags &= ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL;
return stream_update_dep_on_attach_data(stream, pq);
return stream_update_dep_on_attach_data(stream, pq, cycle);
}
int nghttp2_stream_check_deferred_data(nghttp2_stream *stream)
@ -665,7 +671,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream,
nghttp2_pq *pq)
nghttp2_pq *pq,
uint64_t cycle)
{
nghttp2_stream *last_sib;
nghttp2_stream *dep_next;
@ -717,7 +724,7 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
root_stream = stream_update_dep_length(dep_stream, delta_substreams);
rv = stream_update_dep_set_top(root_stream, pq);
rv = stream_update_dep_set_top(root_stream, pq, cycle);
if(rv != 0) {
return rv;
@ -731,7 +738,8 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream,
nghttp2_pq *pq)
nghttp2_pq *pq,
uint64_t cycle)
{
nghttp2_stream *last_sib;
nghttp2_stream *root_stream;
@ -761,7 +769,7 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
root_stream = stream_update_dep_length(dep_stream, stream->num_substreams);
rv = stream_update_dep_set_top(root_stream, pq);
rv = stream_update_dep_set_top(root_stream, pq, cycle);
if(rv != 0) {
return rv;
@ -824,7 +832,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream)
stream->dep_prev = NULL;
}
int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle)
{
int rv;
@ -837,7 +846,7 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
stream->effective_weight = stream->weight;
rv = stream_update_dep_set_top(stream, pq);
rv = stream_update_dep_set_top(stream, pq, cycle);
if(rv != 0) {
return rv;
@ -850,7 +859,7 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
}
int nghttp2_stream_dep_all_your_stream_are_belong_to_us
(nghttp2_stream *stream, nghttp2_pq *pq)
(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle)
{
nghttp2_stream *first, *si;
@ -905,7 +914,7 @@ int nghttp2_stream_dep_all_your_stream_are_belong_to_us
nghttp2_stream_roots_remove_all(stream->roots);
return nghttp2_stream_dep_make_root(stream, pq);
return nghttp2_stream_dep_make_root(stream, pq, cycle);
}
int nghttp2_stream_in_dep_tree(nghttp2_stream *stream)

View File

@ -209,7 +209,7 @@ void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag);
* Out of memory
*/
int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
nghttp2_pq *pq);
nghttp2_pq *pq, uint64_t cycle);
/*
* Detaches deferred data in this stream and it is back to active
@ -218,7 +218,7 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
* set.
*/
int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream,
nghttp2_pq *pq);
nghttp2_pq *pq, uint64_t cycle);
/*
* Returns nonzero if data item is deferred by whatever reason.
@ -329,7 +329,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream);
*/
int nghttp2_stream_attach_data(nghttp2_stream *stream,
nghttp2_outbound_item *data_item,
nghttp2_pq *pq);
nghttp2_pq *pq,
uint64_t cycle);
/*
* Detaches |stream->data_item|. Updates dpri members in this
@ -342,7 +343,8 @@ int nghttp2_stream_attach_data(nghttp2_stream *stream,
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq);
int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle);
/*
@ -357,7 +359,8 @@ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq);
*/
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream,
nghttp2_pq *pq);
nghttp2_pq *pq,
uint64_t cycle);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
@ -371,7 +374,8 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
*/
int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream,
nghttp2_pq *pq);
nghttp2_pq *pq,
uint64_t cycle);
/*
* Removes subtree whose root stream is |stream|. Removing subtree
@ -396,7 +400,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq);
int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq,
uint64_t cycle);
/*
* Makes the |stream| as root and all existing root streams become
@ -409,7 +414,7 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq);
* Out of memory
*/
int nghttp2_stream_dep_all_your_stream_are_belong_to_us
(nghttp2_stream *stream, nghttp2_pq *pq);
(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle);
/*
* Returns nonzero if |stream| is in any dependency tree.

View File

@ -2222,7 +2222,8 @@ void test_nghttp2_session_on_window_update_received(void)
data_item->frame_cat = NGHTTP2_CAT_DATA;
CU_ASSERT(0 == nghttp2_stream_attach_data(stream, data_item,
&session->ob_pq));
&session->ob_pq,
session->last_cycle));
nghttp2_frame_window_update_init(&frame.window_update, NGHTTP2_FLAG_NONE,
1, 16*1024);
@ -2233,7 +2234,7 @@ void test_nghttp2_session_on_window_update_received(void)
CU_ASSERT(0 == nghttp2_stream_defer_data
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
&session->ob_pq));
&session->ob_pq, session->last_cycle));
CU_ASSERT(0 == nghttp2_session_on_window_update_received(session, &frame));
CU_ASSERT(2 == user_data.frame_recv_cb_called);
@ -5270,7 +5271,7 @@ void test_nghttp2_session_stream_dep_add_subtree(void)
* d
*/
nghttp2_stream_dep_add_subtree(a, e, &session->ob_pq);
nghttp2_stream_dep_add_subtree(a, e, &session->ob_pq, session->last_cycle);
/* becomes
* a
@ -5321,7 +5322,7 @@ void test_nghttp2_session_stream_dep_add_subtree(void)
* d
*/
nghttp2_stream_dep_insert_subtree(a, e, &session->ob_pq);
nghttp2_stream_dep_insert_subtree(a, e, &session->ob_pq, session->last_cycle);
/* becomes
* a
@ -5514,7 +5515,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void)
nghttp2_stream_dep_remove_subtree(c);
CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us
(c, &session->ob_pq));
(c, &session->ob_pq, session->last_cycle));
/*
* c
@ -5552,7 +5553,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void)
nghttp2_stream_dep_remove_subtree(c);
CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us
(c, &session->ob_pq));
(c, &session->ob_pq, session->last_cycle));
/*
* c
@ -5589,7 +5590,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void)
nghttp2_stream_dep_remove_subtree(c);
CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us
(c, &session->ob_pq));
(c, &session->ob_pq, session->last_cycle));
/*
* c
@ -5642,7 +5643,7 @@ void test_nghttp2_session_stream_attach_data(void)
db = create_data_ob_item();
nghttp2_stream_attach_data(b, db, &session->ob_pq);
nghttp2_stream_attach_data(b, db, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5657,7 +5658,7 @@ void test_nghttp2_session_stream_attach_data(void)
dc = create_data_ob_item();
nghttp2_stream_attach_data(c, dc, &session->ob_pq);
nghttp2_stream_attach_data(c, dc, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5673,7 +5674,7 @@ void test_nghttp2_session_stream_attach_data(void)
da = create_data_ob_item();
nghttp2_stream_attach_data(a, da, &session->ob_pq);
nghttp2_stream_attach_data(a, da, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == b->dpri);
@ -5684,7 +5685,7 @@ void test_nghttp2_session_stream_attach_data(void)
CU_ASSERT(1 == da->queued);
nghttp2_stream_detach_data(a, &session->ob_pq);
nghttp2_stream_detach_data(a, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5696,7 +5697,7 @@ void test_nghttp2_session_stream_attach_data(void)
dd = create_data_ob_item();
nghttp2_stream_attach_data(d, dd, &session->ob_pq);
nghttp2_stream_attach_data(d, dd, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5708,7 +5709,7 @@ void test_nghttp2_session_stream_attach_data(void)
CU_ASSERT(0 == dd->queued);
nghttp2_stream_detach_data(c, &session->ob_pq);
nghttp2_stream_detach_data(c, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5751,11 +5752,11 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
de = create_data_ob_item();
nghttp2_stream_attach_data(e, de, &session->ob_pq);
nghttp2_stream_attach_data(e, de, &session->ob_pq, session->last_cycle);
db = create_data_ob_item();
nghttp2_stream_attach_data(b, db, &session->ob_pq);
nghttp2_stream_attach_data(b, db, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5770,7 +5771,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Insert subtree e under a */
nghttp2_stream_dep_remove_subtree(e);
nghttp2_stream_dep_insert_subtree(a, e, &session->ob_pq);
nghttp2_stream_dep_insert_subtree(a, e, &session->ob_pq, session->last_cycle);
/*
* a
@ -5795,7 +5796,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
nghttp2_stream_dep_remove_subtree(b);
nghttp2_stream_dep_make_root(b, &session->ob_pq);
nghttp2_stream_dep_make_root(b, &session->ob_pq, session->last_cycle);
/*
* a b
@ -5821,7 +5822,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
nghttp2_stream_dep_remove_subtree(a);
nghttp2_stream_dep_make_root(a, &session->ob_pq);
nghttp2_stream_dep_make_root(a, &session->ob_pq, session->last_cycle);
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri);
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri);
@ -5834,7 +5835,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
nghttp2_stream_dep_remove_subtree(c);
nghttp2_stream_dep_make_root(c, &session->ob_pq);
nghttp2_stream_dep_make_root(c, &session->ob_pq, session->last_cycle);
/*
* a b c
@ -5853,12 +5854,12 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
dd = create_data_ob_item();
nghttp2_stream_attach_data(d, dd, &session->ob_pq);
nghttp2_stream_attach_data(d, dd, &session->ob_pq, session->last_cycle);
/* Add subtree c to a */
nghttp2_stream_dep_remove_subtree(c);
nghttp2_stream_dep_add_subtree(a, c, &session->ob_pq);
nghttp2_stream_dep_add_subtree(a, c, &session->ob_pq, session->last_cycle);
/*
* a b
@ -5885,7 +5886,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Insert b under a */
nghttp2_stream_dep_remove_subtree(b);
nghttp2_stream_dep_insert_subtree(a, b, &session->ob_pq);
nghttp2_stream_dep_insert_subtree(a, b, &session->ob_pq, session->last_cycle);
/*
* a
@ -5912,7 +5913,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Remove subtree b */
nghttp2_stream_dep_remove_subtree(b);
nghttp2_stream_dep_make_root(b, &session->ob_pq);
nghttp2_stream_dep_make_root(b, &session->ob_pq, session->last_cycle);
/*
* b a