Commit ac86b51e authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Implement simplified dependency based priority

parent 27a91fc3
This diff is collapsed.
......@@ -74,7 +74,12 @@ void nghttp2_frame_headers_init(nghttp2_headers *frame,
frame->nva = nva;
frame->nvlen = nvlen;
frame->cat = NGHTTP2_HCAT_REQUEST;
frame->pri_spec = *pri_spec;
if(pri_spec) {
frame->pri_spec = *pri_spec;
} else {
nghttp2_priority_spec_default_init(&frame->pri_spec);
}
}
void nghttp2_frame_headers_free(nghttp2_headers *frame)
......@@ -85,22 +90,8 @@ void nghttp2_frame_headers_free(nghttp2_headers *frame)
void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
const nghttp2_priority_spec *pri_spec)
{
uint8_t flags;
switch(pri_spec->pri_type) {
case NGHTTP2_PRIORITY_TYPE_GROUP:
flags = NGHTTP2_FLAG_PRIORITY_GROUP;
break;
case NGHTTP2_PRIORITY_TYPE_DEP:
flags = NGHTTP2_FLAG_PRIORITY_DEPENDENCY;
break;
default:
assert(0);
}
nghttp2_frame_set_hd(&frame->hd, 4, NGHTTP2_PRIORITY, flags, stream_id);
nghttp2_frame_set_hd(&frame->hd, 5, NGHTTP2_PRIORITY, NGHTTP2_FLAG_NONE,
stream_id);
frame->pri_spec = *pri_spec;
}
......@@ -261,14 +252,10 @@ void nghttp2_frame_private_data_free(nghttp2_private_data *frame)
size_t nghttp2_frame_priority_len(uint8_t flags)
{
if(flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
if(flags & NGHTTP2_FLAG_PRIORITY) {
return 5;
}
if(flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
return 4;
}
return 0;
}
......@@ -375,7 +362,9 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs,
return rv;
}
nghttp2_frame_pack_priority_spec(buf->pos, &frame->pri_spec);
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
nghttp2_frame_pack_priority_spec(buf->pos, &frame->pri_spec);
}
frame->padlen = 0;
frame->hd.length = nghttp2_bufs_len(bufs);
......@@ -386,24 +375,11 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs,
void nghttp2_frame_pack_priority_spec(uint8_t *buf,
const nghttp2_priority_spec *pri_spec)
{
switch(pri_spec->pri_type) {
case NGHTTP2_PRIORITY_TYPE_GROUP:
nghttp2_put_uint32be(buf, pri_spec->spec.group.pri_group_id);
buf[4] = pri_spec->spec.group.weight - 1;
return;
case NGHTTP2_PRIORITY_TYPE_DEP:
nghttp2_put_uint32be(buf, pri_spec->spec.dep.stream_id);
if(pri_spec->spec.dep.exclusive) {
buf[0] |= 0x80;
}
return;
default:
return;
nghttp2_put_uint32be(buf, pri_spec->stream_id);
if(pri_spec->exclusive) {
buf[0] |= 0x80;
}
buf[4] = pri_spec->weight - 1;
}
void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
......@@ -411,33 +387,28 @@ void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
const uint8_t *payload,
size_t payloadlen)
{
if(flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
int32_t pri_group_id;
int32_t weight;
pri_group_id = nghttp2_get_uint32(payload) & NGHTTP2_PRI_GROUP_ID_MASK;
weight = payload[4] + 1;
nghttp2_priority_spec_group_init(pri_spec, pri_group_id, weight);
} else if(flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
int32_t dep_stream_id;
uint8_t exclusive;
int32_t dep_stream_id;
uint8_t exclusive;
int32_t weight;
dep_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
exclusive = (payload[0] & 0x80) > 0;
dep_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
exclusive = (payload[0] & 0x80) > 0;
weight = payload[4] + 1;
nghttp2_priority_spec_dep_init(pri_spec, dep_stream_id, exclusive);
} else {
pri_spec->pri_type = NGHTTP2_PRIORITY_TYPE_NONE;
}
nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive);
}
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
const uint8_t *payload,
size_t payloadlen)
{
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, frame->hd.flags,
payload, payloadlen);
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, frame->hd.flags,
payload, payloadlen);
} else {
nghttp2_priority_spec_default_init(&frame->pri_spec);
}
frame->nva = NULL;
frame->nvlen = 0;
......@@ -457,7 +428,7 @@ int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame)
nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec);
buf->last += nghttp2_frame_priority_len(frame->hd.flags);
buf->last += 5;
return 0;
}
......
......@@ -155,7 +155,8 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs,
/*
* Unpacks HEADERS frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block.
* only unapcks bytes that come before name/value header block and
* after PAD_HIGH and PAD_LOW.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
......
......@@ -24,18 +24,25 @@
*/
#include "nghttp2_priority_spec.h"
void nghttp2_priority_spec_group_init(nghttp2_priority_spec *pri_spec,
int32_t pri_group_id, int32_t weight)
void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
int32_t stream_id, int32_t weight,
int exclusive)
{
pri_spec->pri_type = NGHTTP2_PRIORITY_TYPE_GROUP;
pri_spec->spec.group.pri_group_id = pri_group_id;
pri_spec->spec.group.weight = weight;
pri_spec->stream_id = stream_id;
pri_spec->weight = weight;
pri_spec->exclusive = exclusive != 0;
}
void nghttp2_priority_spec_dep_init(nghttp2_priority_spec *pri_spec,
int32_t stream_id, int exclusive)
void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec)
{
pri_spec->pri_type = NGHTTP2_PRIORITY_TYPE_DEP;
pri_spec->spec.dep.stream_id = stream_id;
pri_spec->spec.dep.exclusive = exclusive != 0;
pri_spec->stream_id = 0;
pri_spec->weight = NGHTTP2_DEFAULT_WEIGHT;
pri_spec->exclusive = 0;
}
int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec)
{
/* Ignore exclusive flag */
return pri_spec->stream_id == 0 &&
pri_spec->weight == NGHTTP2_DEFAULT_WEIGHT;
}
This diff is collapsed.
......@@ -117,7 +117,6 @@ typedef enum {
struct nghttp2_session {
nghttp2_map /* <nghttp2_stream*> */ streams;
nghttp2_map /* <nghttp2_stream_group*> */ stream_groups;
/* Queue for outbound frames other than stream-creating HEADERS */
nghttp2_pq /* <nghttp2_outbound_item*> */ ob_pq;
/* Queue for outbound stream-creating HEADERS frame */
......@@ -603,14 +602,6 @@ nghttp2_stream* nghttp2_session_get_stream(nghttp2_session *session,
nghttp2_stream* nghttp2_session_get_stream_raw(nghttp2_session *session,
int32_t stream_id);
/*
* Returns nghttp2_stream_group* object whose priority group ID is
* |pri_group_id|. It could be NULL if such priority group does not
* exist.
*/
nghttp2_stream_group* nghttp2_session_get_stream_group
(nghttp2_session *session, int32_t pri_group_id);
/*
* Packs DATA frame |frame| in wire frame format and stores it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
......@@ -698,19 +689,4 @@ int nghttp2_session_reprioritize_stream
(nghttp2_session *session, nghttp2_stream *stream,
const nghttp2_priority_spec *pri_spec);
/*
* Creates new priority group using given values.
*
* This function returns created priority group if it succeeds, or
* NULL.
*/
nghttp2_stream_group* nghttp2_session_open_stream_group
(nghttp2_session *session, int32_t pri_group_id, int32_t weight);
/*
* Closes priority group if it does not include any streams.
*/
void nghttp2_session_close_stream_group_if_empty
(nghttp2_session *session, nghttp2_stream_group *stream_group);
#endif /* NGHTTP2_SESSION_H */
This diff is collapsed.
......@@ -102,10 +102,6 @@ typedef enum {
NGHTTP2_STREAM_DPRI_REST = 0x04
} nghttp2_stream_dpri;
struct nghttp2_stream_group;
typedef struct nghttp2_stream_group nghttp2_stream_group;
struct nghttp2_stream;
typedef struct nghttp2_stream nghttp2_stream;
......@@ -133,16 +129,11 @@ struct nghttp2_stream {
nghttp2_outbound_item *data_item;
/* stream ID */
int32_t stream_id;
/* priority group this stream belongs to */
nghttp2_stream_group *stream_group;
/* categorized priority of this stream. Only stream bearing
NGHTTP2_STREAM_DPRI_TOP can send DATA frame. */
nghttp2_stream_dpri dpri;
/* the number of streams in subtree */
size_t num_substreams;
/* the number of streams marked as NGHTTP2_STREAM_DPRI_TOP in
subtree */
ssize_t num_subtop;
/* Current remote window size. This value is computed against the
current initial window size of remote endpoint. */
int32_t remote_window_size;
......@@ -157,6 +148,12 @@ struct nghttp2_stream {
NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
int32_t local_window_size;
/* weight of this stream */
int32_t weight;
/* effective weight of this stream in belonging dependency tree */
int32_t effective_weight;
/* sum of weight (not effective_weight) of direct descendants */
int32_t sum_dep_weight;
nghttp2_stream_state state;
/* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */
uint8_t flags;
......@@ -167,6 +164,7 @@ struct nghttp2_stream {
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags,
nghttp2_stream_state initial_state,
int32_t weight,
int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data);
......@@ -259,12 +257,30 @@ nghttp2_stream* nghttp2_stream_get_dep_root(nghttp2_stream *stream);
int nghttp2_stream_dep_subtree_find(nghttp2_stream *stream,
nghttp2_stream *target);
/*
* Computes distributed weight of a stream of the |weight| under the
* |stream| if |stream| is removed from a dependency tree. The result
* is computed using stream->weight rather than
* stream->effective_weight.
*/
int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
int32_t weight);
/*
* Computes effective weight of a stream of the |weight| under the
* |stream|. The result is computed using stream->effective_weight
* rather than stream->weight. This function is used to determine
* weight in dependency tree.
*/
int32_t nghttp2_stream_dep_distributed_effective_weight
(nghttp2_stream *stream, int32_t weight);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* exclusive. All existing direct descendants of |dep_stream| become
* the descendants of the |stream|. This function assumes
* |stream->data| is NULL and no dpri members are changed in this
* dependency tree. It also does not change stream->stream_group.
* dependency tree.
*/
void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
nghttp2_stream *stream);
......@@ -272,8 +288,7 @@ void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* not exclusive. This function assumes |stream->data| is NULL and no
* dpri members are changed in this dependency tree. It also does not
* change stream->stream_group.
* dpri members are changed in this dependency tree.
*/
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
nghttp2_stream *stream);
......@@ -342,8 +357,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
/*
* Removes subtree whose root stream is |stream|. Removing subtree
* does not change dpri values and removed subtree is still in the
* same stream_group.
* does not change dpri values. The effective_weight of streams in
* removed subtree is not updated.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
......@@ -354,8 +369,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
/*
* Makes the |stream| as root for |stream_group|. Updates dpri
* members in this dependency tree.
* Makes the |stream| as root. Updates dpri members in this
* dependency tree.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
......@@ -363,53 +378,6 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_dep_make_root(nghttp2_stream_group *stream_group,
nghttp2_stream *stream,
nghttp2_pq *pq);
/*
* Priority group of streams.
*/
struct nghttp2_stream_group {
/* Intrusive Map */
nghttp2_map_entry map_entry;
/* The number of streams this priority group contains */
size_t num_streams;
/* The number of streams marked as NGHTTP2_STREAM_DPRI_TOP */
ssize_t num_top;
/* The priority group ID */
int32_t pri_group_id;
/* The weight of this group */
int32_t weight;
};
void nghttp2_stream_group_init(nghttp2_stream_group *stream_group,
int32_t pri_group_id,
int32_t weight);
void nghttp2_stream_group_free(nghttp2_stream_group *stream_group);
/*
* Adds |stream| to |stream_group|.
*/
void nghttp2_stream_group_add_stream(nghttp2_stream_group *stream_group,
nghttp2_stream *stream);
/*
* Removes |stream| from |stream_group|.
*/
void nghttp2_stream_group_remove_stream(nghttp2_stream_group *stream_group,
nghttp2_stream *stream);
/*
* Updates |stream_group->num_top| += |delta|
*/
void nghttp2_stream_group_update_num_top(nghttp2_stream_group *stream_group,
ssize_t delta);
/*
* Returns shared weight among the streams belongs to |stream_group|.
*/
size_t nghttp2_stream_group_shared_wait(nghttp2_stream_group *stream_group);
int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq);
#endif /* NGHTTP2_STREAM */
......@@ -77,8 +77,7 @@ static int nghttp2_submit_headers_shared
flags_copy =
(flags & (NGHTTP2_FLAG_END_STREAM |
NGHTTP2_FLAG_END_SEGMENT |
NGHTTP2_FLAG_PRIORITY_GROUP |
NGHTTP2_FLAG_PRIORITY_DEPENDENCY)) |
NGHTTP2_FLAG_PRIORITY)) |
NGHTTP2_FLAG_END_HEADERS;
nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, pri_spec,
......@@ -102,14 +101,16 @@ static int nghttp2_submit_headers_shared
return rv;
}
static void adjust_priority_spec_group_weight(nghttp2_priority_spec *pri_spec)
static void adjust_priority_spec_weight(nghttp2_priority_spec *pri_spec)
{
assert(pri_spec->pri_type == NGHTTP2_PRIORITY_TYPE_GROUP);
if(pri_spec->stream_id == 0) {
pri_spec->exclusive = 0;
}
if(pri_spec->spec.group.weight < NGHTTP2_MIN_WEIGHT) {
pri_spec->spec.group.weight = NGHTTP2_MIN_WEIGHT;
} else if(pri_spec->spec.group.weight > NGHTTP2_MAX_WEIGHT) {
pri_spec->spec.group.weight = NGHTTP2_MAX_WEIGHT;
if(pri_spec->weight < NGHTTP2_MIN_WEIGHT) {
pri_spec->weight = NGHTTP2_MIN_WEIGHT;
} else if(pri_spec->weight > NGHTTP2_MAX_WEIGHT) {
pri_spec->weight = NGHTTP2_MAX_WEIGHT;
}
}
......@@ -125,25 +126,13 @@ static int nghttp2_submit_headers_shared_nva
{
ssize_t rv;
nghttp2_nv *nva_copy;
nghttp2_priority_spec copy_pri_spec = {
NGHTTP2_PRIORITY_TYPE_NONE
};
nghttp2_priority_spec copy_pri_spec;
if(pri_spec) {
switch(pri_spec->pri_type) {
case NGHTTP2_PRIORITY_TYPE_NONE:
case NGHTTP2_PRIORITY_TYPE_GROUP:
case NGHTTP2_PRIORITY_TYPE_DEP:
break;
default:
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
copy_pri_spec = *pri_spec;
if(copy_pri_spec.pri_type == NGHTTP2_PRIORITY_TYPE_GROUP) {
adjust_priority_spec_group_weight(&copy_pri_spec);
}
adjust_priority_spec_weight(&copy_pri_spec);
} else {
nghttp2_priority_spec_default_init(&copy_pri_spec);
}
rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen);
......@@ -164,20 +153,10 @@ int nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
{
flags &= NGHTTP2_FLAG_END_STREAM;
if(pri_spec) {
switch(pri_spec->pri_type) {
case NGHTTP2_PRIORITY_TYPE_GROUP:
flags |= NGHTTP2_FLAG_PRIORITY_GROUP;
break;
case NGHTTP2_PRIORITY_TYPE_DEP:
flags |= NGHTTP2_FLAG_PRIORITY_DEPENDENCY;
break;
default:
/* Default weight */
pri_spec = NULL;
break;
}
if(pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
flags |= NGHTTP2_FLAG_PRIORITY;
} else {
pri_spec = NULL;
}
return nghttp2_submit_headers_shared_nva(session, flags, stream_id, pri_spec,
......@@ -203,23 +182,14 @@ int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
copy_pri_spec = *pri_spec;
switch(copy_pri_spec.pri_type) {
case NGHTTP2_PRIORITY_TYPE_GROUP:
adjust_priority_spec_group_weight(&copy_pri_spec);
break;
case NGHTTP2_PRIORITY_TYPE_DEP:
if(stream_id == copy_pri_spec.spec.dep.stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
break;
default:
if(stream_id == pri_spec->stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
copy_pri_spec = *pri_spec;
adjust_priority_spec_weight(&copy_pri_spec);
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
......@@ -433,17 +403,7 @@ static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
}
if(pri_spec) {
switch(pri_spec->pri_type) {
case NGHTTP2_PRIORITY_TYPE_GROUP:
flags |= NGHTTP2_FLAG_PRIORITY_GROUP;
break;
case NGHTTP2_PRIORITY_TYPE_DEP:
flags |= NGHTTP2_FLAG_PRIORITY_DEPENDENCY;
break;
default:
/* Default weight */
break;
}
flags |= NGHTTP2_FLAG_PRIORITY;
}
return flags;
......@@ -457,6 +417,10 @@ int nghttp2_submit_request(nghttp2_session *session,
{
uint8_t flags;
if(pri_spec && nghttp2_priority_spec_check_default(pri_spec)) {
pri_spec = NULL;
}
flags = set_request_flags(pri_spec, data_prd);
return nghttp2_submit_headers_shared_nva(session, flags, -1, pri_spec,
......
......@@ -261,27 +261,15 @@ void print_flags(const nghttp2_frame_hd& hd)
}
s += "PAD_HIGH";
}
if(hd.flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
if(hd.flags & NGHTTP2_FLAG_PRIORITY) {
if(!s.empty()) {
s += " | ";
}
s += "PRIORITY_GROUP";
}
if(hd.flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
if(!s.empty()) {
s += " | ";
}
s += "PRIORITY_DEPENDENCY";
s += "PRIORITY";
}
break;
case NGHTTP2_PRIORITY:
if(hd.flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
s += "PRIORITY_GROUP";
} else if(hd.flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
s += "PRIORITY_DEPENDENCY";
}
break;
case NGHTTP2_SETTINGS:
if(hd.flags & NGHTTP2_FLAG_ACK) {
......@@ -368,14 +356,11 @@ void print_frame(print_type ptype, const nghttp2_frame *frame)
case NGHTTP2_HEADERS:
print_frame_attr_indent();
fprintf(outfile, "(padlen=%zu", frame->headers.padlen);
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
fprintf(outfile, ", pri_group_id=%d, weight=%u",
frame->headers.pri_spec.spec.group.pri_group_id,
frame->headers.pri_spec.spec.group.weight);
} else if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
fprintf(outfile, ", stream_id=%d, exclusive=%d",
frame->headers.pri_spec.spec.dep.stream_id,
frame->headers.pri_spec.spec.dep.exclusive);
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
fprintf(outfile, ", stream_id=%d, weight=%u, exclusive=%d",
frame->headers.pri_spec.stream_id,
frame->headers.pri_spec.weight,
frame->headers.pri_spec.exclusive);
}
fprintf(outfile, ")\n");
switch(frame->headers.cat) {
......@@ -399,19 +384,10 @@ void print_frame(print_type ptype, const nghttp2_frame *frame)
case NGHTTP2_PRIORITY:
print_frame_attr_indent();
fprintf(outfile, "(");
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY_GROUP) {
fprintf(outfile, "pri_group_id=%d, weight=%u",
frame->priority.pri_spec.spec.group.pri_group_id,
frame->priority.pri_spec.spec.group.weight);
} else if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY_DEPENDENCY) {
fprintf(outfile, "stream_id=%d, exclusive=%d",
frame->priority.pri_spec.spec.dep.stream_id,
frame->priority.pri_spec.spec.dep.exclusive);
}
fprintf(outfile, ")\n");
fprintf(outfile, "(stream_id=%d, weight=%u, exclusive=%d)\n",
frame->priority.pri_spec.stream_id,
frame->priority.pri_spec.weight,
frame->priority.pri_spec.exclusive);
break;
case NGHTTP2_RST_STREAM:
......
......@@ -263,7 +263,7 @@ struct Request {
nghttp2_priority_spec resolve_dep(int32_t pri)
{
nghttp2_priority_spec pri_spec = { NGHTTP2_PRIORITY_TYPE_NONE };
nghttp2_priority_spec pri_spec;
int exclusive = 0;
int32_t stream_id = -1;
......@@ -271,6 +271,8 @@ struct Request {
return pri_spec;
}
nghttp2_priority_spec_default_init(&pri_spec);
auto start = std::min(pri, (int)dep->deps.size() - 1);
for(auto i = start; i >= 0; --i) {
......@@ -293,7 +295,8 @@ struct Request {
return pri_spec;
}
nghttp2_priority_spec_dep_init(&pri_spec, stream_id, exclusive);
nghttp2_priority_spec_init(&pri_spec, stream_id, NGHTTP2_DEFAULT_WEIGHT,
exclusive);
return pri_spec;
}
......@@ -1014,12 +1017,9 @@ void update_html_parser(HttpClient *client, Request *req,
nghttp2_priority_spec pri_spec;
// We always specify priority group of parent stream, so that
// even if the parent stream is closed, the dependent stream is
// in the same priority group. We adjust the priority using
// separate PRIORITY frame after stream ID becomes known.
nghttp2_priority_spec_group_init(&pri_spec, req->stream_id,
config.weight);
// We adjust the priority using separate PRIORITY frame after
// stream ID becomes known.
nghttp2_priority_spec_default_init(&pri_spec);
if ( client->add_request(uri, nullptr, 0, pri_spec, req->dep,
req->level+1) ) {
......@@ -1108,9 +1108,8 @@ void check_stream_id(nghttp2_session *session, int32_t stream_id,
auto pri_spec = req->resolve_dep(req->pri);
if(pri_spec.pri_type == NGHTTP2_PRIORITY_TYPE_DEP) {
nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, stream_id,
&pri_spec);
if(!nghttp2_priority_spec_check_default(&pri_spec)) {
nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, stream_id, &pri_spec);
}
auto itr = std::begin(req->dep->deps);
......@@ -1208,7 +1207,9 @@ int on_begin_headers_callback(nghttp2_session *session,
http_parser_url u;
memset(&u, 0, sizeof(u));
// TODO Set pri and level
nghttp2_priority_spec pri_spec = { NGHTTP2_PRIORITY_TYPE_NONE };
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_default_init(&pri_spec);
auto req = util::make_unique<Request>("", u, nullptr, 0, pri_spec,
nullptr);
......@@ -1624,10 +1625,12 @@ int communicate(const std::string& scheme, const std::string& host,
{
HttpClient client{callbacks, evbase, ssl_ctx};
nghttp2_priority_spec pri_spec = { NGHTTP2_PRIORITY_TYPE_NONE };
nghttp2_priority_spec pri_spec;
if(config.weight != NGHTTP2_DEFAULT_WEIGHT) {
nghttp2_priority_spec_group_init(&pri_spec, -1, config.weight);
nghttp2_priority_spec_init(&pri_spec, 0, config.weight, 0);
} else {
nghttp2_priority_spec_default_init(&pri_spec);
}
for(auto req : requests) {
......
......@@ -226,6 +226,8 @@ int main(int argc, char* argv[])
test_nghttp2_session_stream_attach_data) ||
!CU_add_test(pSuite, "session_stream_attach_data_subtree",
test_nghttp2_session_stream_attach_data_subtree) ||
!CU_add_test(pSuite, "session_stream_dep_effective_weight",
test_nghttp2_session_stream_dep_effective_weight) ||
!CU_add_test(pSuite, "session_stream_keep_closed_stream",
test_nghttp2_session_keep_closed_stream) ||
!CU_add_test(pSuite, "frame_pack_headers",
......
......@@ -92,7 +92,7 @@ void test_nghttp2_frame_pack_headers()
nva = headers();
nvlen = HEADERS_LENGTH;
pri_spec.pri_type = NGHTTP2_PRIORITY_TYPE_NONE;
nghttp2_priority_spec_default_init(&pri_spec);
nghttp2_frame_headers_init(&frame,
NGHTTP2_FLAG_END_STREAM |
......@@ -110,8 +110,8 @@ void test_nghttp2_frame_pack_headers()
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS,
1000000007, &oframe.hd);
/* We include NGHTTP2_PRIORITY_TYPE_NONE */
CU_ASSERT(NGHTTP2_PRIORITY_TYPE_NONE == oframe.pri_spec.pri_type);
/* We did not include PRIORITY flag */
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == oframe.pri_spec.weight);
hdblocklen = nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN;
CU_ASSERT(hdblocklen ==
......@@ -126,9 +126,9 @@ void test_nghttp2_frame_pack_headers()
nghttp2_bufs_reset(&bufs);
memset(&oframe, 0, sizeof(oframe));
/* Next, include NGHTTP2_PRIORITY_TYPE_GROUP */
nghttp2_priority_spec_group_init(&frame.pri_spec, 1000000009, 12);
frame.hd.flags |= NGHTTP2_FLAG_PRIORITY_GROUP;
/* Next, include NGHTTP2_FLAG_PRIORITY */
nghttp2_priority_spec_init(&frame.pri_spec, 1000000009, 12, 1);
frame.hd.flags |= NGHTTP2_FLAG_PRIORITY;
rv = nghttp2_frame_pack_headers(&bufs, &frame, &deflater);
......@@ -139,12 +139,12 @@ void test_nghttp2_frame_pack_headers()
check_frame_header(nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY_GROUP,
NGHTTP2_FLAG_PRIORITY,
1000000007, &oframe.hd);
CU_ASSERT(NGHTTP2_PRIORITY_TYPE_GROUP == oframe.pri_spec.pri_type);
CU_ASSERT(1000000009 == oframe.pri_spec.spec.group.pri_group_id);
CU_ASSERT(12 == oframe.pri_spec.spec.group.weight);
CU_ASSERT(1000000009 == oframe.pri_spec.stream_id);
CU_ASSERT(12 == oframe.pri_spec.weight);
CU_ASSERT(1 == oframe.pri_spec.exclusive);
hdblocklen = nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN
- nghttp2_frame_priority_len(oframe.hd.flags);
......@@ -159,44 +159,7 @@ void test_nghttp2_frame_pack_headers()
nva_out_reset(&out);
nghttp2_bufs_reset(&bufs);
memset(&oframe, 0, sizeof(oframe));
/* Next, include NGHTTP2_PRIORITY_TYPE_DEP */
nghttp2_priority_spec_dep_init(&frame.pri_spec, 123, 1);
frame.hd.flags =
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY_DEPENDENCY;
rv = nghttp2_frame_pack_headers(&bufs, &frame, &deflater);
CU_ASSERT(0 == rv);
CU_ASSERT(nghttp2_bufs_len(&bufs) > 0);
CU_ASSERT(0 == unpack_framebuf((nghttp2_frame*)&oframe, &bufs));
check_frame_header(nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY_DEPENDENCY,
1000000007, &oframe.hd);
CU_ASSERT(NGHTTP2_PRIORITY_TYPE_DEP == oframe.pri_spec.pri_type);
CU_ASSERT(123 == oframe.pri_spec.spec.dep.stream_id);
CU_ASSERT(1 == oframe.pri_spec.spec.dep.exclusive);
hdblocklen = nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN
- nghttp2_frame_priority_len(oframe.hd.flags);
CU_ASSERT(hdblocklen ==
inflate_hd(&inflater, &out, &bufs, NGHTTP2_FRAME_HDLEN
+ nghttp2_frame_priority_len(oframe.hd.flags)));
nghttp2_nv_array_sort(out.nva, out.nvlen);
CU_ASSERT(nvnameeq("method", &out.nva[0]));
nghttp2_frame_headers_free(&oframe);
nva_out_reset(&out);
nghttp2_bufs_free(&bufs);
nghttp2_frame_headers_free(&frame);
nghttp2_hd_inflate_free(&inflater);
nghttp2_hd_deflate_free(&deflater);
......@@ -208,7 +171,6 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
nghttp2_headers frame;
nghttp2_bufs bufs;
nghttp2_nv *nva;
nghttp2_priority_spec pri_spec;
ssize_t nvlen;
size_t big_vallen = NGHTTP2_HD_MAX_VALUE;
nghttp2_nv big_hds[16];
......@@ -228,13 +190,11 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
big_hds[i].flags = NGHTTP2_NV_FLAG_NONE;
}
pri_spec.pri_type = NGHTTP2_PRIORITY_TYPE_NONE;
nvlen = nghttp2_nv_array_copy(&nva, big_hds, big_hdslen);
nghttp2_hd_deflate_init(&deflater);
nghttp2_frame_headers_init(&frame,
NGHTTP2_FLAG_END_STREAM|NGHTTP2_FLAG_END_HEADERS,
1000000007, &pri_spec, nva, nvlen);
1000000007, NULL, nva, nvlen);
rv = nghttp2_frame_pack_headers(&bufs, &frame, &deflater);
CU_ASSERT(NGHTTP2_ERR_HEADER_COMP == rv);
......@@ -256,7 +216,7 @@ void test_nghttp2_frame_pack_priority(void)
frame_pack_bufs_init(&bufs);
/* First, pack priority with priority group and weight */
nghttp2_priority_spec_group_init(&pri_spec, 1000000009, 12);
nghttp2_priority_spec_init(&pri_spec, 1000000009, 12, 1);
nghttp2_frame_priority_init(&frame, 1000000007, &pri_spec);
rv = nghttp2_frame_pack_priority(&bufs, &frame);
......@@ -264,34 +224,12 @@ void test_nghttp2_frame_pack_priority(void)
CU_ASSERT(0 == rv);
CU_ASSERT(13 == nghttp2_bufs_len(&bufs));
CU_ASSERT(0 == unpack_framebuf((nghttp2_frame*)&oframe, &bufs));
check_frame_header(4, NGHTTP2_PRIORITY, NGHTTP2_FLAG_PRIORITY_GROUP,
1000000007, &oframe.hd);
CU_ASSERT(NGHTTP2_PRIORITY_TYPE_GROUP == oframe.pri_spec.pri_type);
CU_ASSERT(1000000009 == oframe.pri_spec.spec.group.pri_group_id);
CU_ASSERT(12 == oframe.pri_spec.spec.group.weight);
nghttp2_frame_priority_free(&oframe);
nghttp2_bufs_reset(&bufs);
memset(&oframe, 0, sizeof(oframe));
/* Next, pack priority with stream dependency */
nghttp2_priority_spec_dep_init(&pri_spec, 79, 1);
nghttp2_frame_priority_init(&frame, 1000000007, &pri_spec);
rv = nghttp2_frame_pack_priority(&bufs, &frame);
CU_ASSERT(0 == rv);
CU_ASSERT(12 == nghttp2_bufs_len(&bufs));
CU_ASSERT(0 == unpack_framebuf((nghttp2_frame*)&oframe, &bufs));
check_frame_header(4, NGHTTP2_PRIORITY, NGHTTP2_FLAG_PRIORITY_DEPENDENCY,
check_frame_header(5, NGHTTP2_PRIORITY, NGHTTP2_FLAG_NONE,
1000000007, &oframe.hd);
CU_ASSERT(NGHTTP2_PRIORITY_TYPE_DEP == oframe.pri_spec.pri_type);
CU_ASSERT(79 == oframe.pri_spec.spec.dep.stream_id);
CU_ASSERT(1 == oframe.pri_spec.spec.dep.exclusive);
CU_ASSERT(1000000009 == oframe.pri_spec.stream_id);
CU_ASSERT(12 == oframe.pri_spec.weight);
CU_ASSERT(1 == oframe.pri_spec.exclusive);
nghttp2_frame_priority_free(&oframe);
nghttp2_bufs_reset(&bufs);
......
This diff is collapsed.
......@@ -105,6 +105,7 @@ void test_nghttp2_session_stream_dep_add_subtree(void);
void test_nghttp2_session_stream_dep_remove_subtree(void);
void test_nghttp2_session_stream_attach_data(void);
void test_nghttp2_session_stream_attach_data_subtree(void);
void test_nghttp2_session_stream_dep_effective_weight(void);
void test_nghttp2_session_keep_closed_stream(void);
#endif /* NGHTTP2_SESSION_TEST_H */
......@@ -236,8 +236,7 @@ nghttp2_stream* open_stream(nghttp2_session *session, int32_t stream_id)
{
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_group_init(&pri_spec, stream_id,
NGHTTP2_DEFAULT_WEIGHT);
nghttp2_priority_spec_default_init(&pri_spec);
return nghttp2_session_open_stream(session, stream_id,
NGHTTP2_STREAM_FLAG_NONE,
......@@ -249,10 +248,19 @@ nghttp2_stream* open_stream(nghttp2_session *session, int32_t stream_id)
nghttp2_stream* open_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream)
{
return open_stream_with_dep_weight(session, stream_id,
NGHTTP2_DEFAULT_WEIGHT, dep_stream);
}
nghttp2_stream* open_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream)
{
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_dep_init(&pri_spec, dep_stream->stream_id, 0);
nghttp2_priority_spec_init(&pri_spec, dep_stream->stream_id, weight, 0);
return nghttp2_session_open_stream(session, stream_id,
NGHTTP2_STREAM_FLAG_NONE,
......@@ -267,7 +275,8 @@ nghttp2_stream* open_stream_with_dep_excl(nghttp2_session *session,
{
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_dep_init(&pri_spec, dep_stream->stream_id, 1);
nghttp2_priority_spec_init(&pri_spec, dep_stream->stream_id,
NGHTTP2_DEFAULT_WEIGHT, 1);
return nghttp2_session_open_stream(session, stream_id,
NGHTTP2_STREAM_FLAG_NONE,
......
......@@ -89,6 +89,11 @@ nghttp2_stream* open_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
nghttp2_stream* open_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream);
nghttp2_stream* open_stream_with_dep_excl(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment