Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
aa4d43f3
Commit
aa4d43f3
authored
Apr 17, 2014
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow exclusive dependency to stream 0
parent
ac86b51e
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
446 additions
and
25 deletions
+446
-25
lib/includes/nghttp2/nghttp2.h
lib/includes/nghttp2/nghttp2.h
+0
-2
lib/nghttp2_priority_spec.c
lib/nghttp2_priority_spec.c
+2
-2
lib/nghttp2_session.c
lib/nghttp2_session.c
+38
-5
lib/nghttp2_session.h
lib/nghttp2_session.h
+1
-0
lib/nghttp2_stream.c
lib/nghttp2_stream.c
+157
-0
lib/nghttp2_stream.h
lib/nghttp2_stream.h
+47
-0
lib/nghttp2_submit.c
lib/nghttp2_submit.c
+0
-4
tests/main.c
tests/main.c
+2
-0
tests/nghttp2_session_test.c
tests/nghttp2_session_test.c
+198
-12
tests/nghttp2_session_test.h
tests/nghttp2_session_test.h
+1
-0
No files found.
lib/includes/nghttp2/nghttp2.h
View file @
aa4d43f3
...
@@ -2105,8 +2105,6 @@ void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec);
...
@@ -2105,8 +2105,6 @@ void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec);
* @function
* @function
*
*
* Returns nonzero if the |pri_spec| is filled with default values.
* Returns nonzero if the |pri_spec| is filled with default values.
* `pri_spec->exclusive` is ignored since it is irrelevant when
* `pri_spec->stream_id == 0`.
*/
*/
int
nghttp2_priority_spec_check_default
(
const
nghttp2_priority_spec
*
pri_spec
);
int
nghttp2_priority_spec_check_default
(
const
nghttp2_priority_spec
*
pri_spec
);
...
...
lib/nghttp2_priority_spec.c
View file @
aa4d43f3
...
@@ -42,7 +42,7 @@ void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec)
...
@@ -42,7 +42,7 @@ void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec)
int
nghttp2_priority_spec_check_default
(
const
nghttp2_priority_spec
*
pri_spec
)
int
nghttp2_priority_spec_check_default
(
const
nghttp2_priority_spec
*
pri_spec
)
{
{
/* Ignore exclusive flag */
return
pri_spec
->
stream_id
==
0
&&
return
pri_spec
->
stream_id
==
0
&&
pri_spec
->
weight
==
NGHTTP2_DEFAULT_WEIGHT
;
pri_spec
->
weight
==
NGHTTP2_DEFAULT_WEIGHT
&&
pri_spec
->
exclusive
==
0
;
}
}
lib/nghttp2_session.c
View file @
aa4d43f3
...
@@ -280,6 +280,8 @@ static int nghttp2_session_new(nghttp2_session **session_ptr,
...
@@ -280,6 +280,8 @@ static int nghttp2_session_new(nghttp2_session **session_ptr,
goto
fail_map
;
goto
fail_map
;
}
}
nghttp2_stream_roots_init
(
&
(
*
session_ptr
)
->
roots
);
(
*
session_ptr
)
->
next_seq
=
0
;
(
*
session_ptr
)
->
next_seq
=
0
;
(
*
session_ptr
)
->
remote_window_size
=
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE
;
(
*
session_ptr
)
->
remote_window_size
=
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE
;
...
@@ -436,6 +438,8 @@ void nghttp2_session_del(nghttp2_session *session)
...
@@ -436,6 +438,8 @@ void nghttp2_session_del(nghttp2_session *session)
}
}
free
(
session
->
inflight_iv
);
free
(
session
->
inflight_iv
);
nghttp2_stream_roots_free
(
&
session
->
roots
);
/* Have to free streams first, so that we can check
/* Have to free streams first, so that we can check
stream->data_item->queued */
stream->data_item->queued */
nghttp2_map_each_free
(
&
session
->
streams
,
nghttp2_free_streams
,
NULL
);
nghttp2_map_each_free
(
&
session
->
streams
,
nghttp2_free_streams
,
NULL
);
...
@@ -470,14 +474,21 @@ int nghttp2_session_reprioritize_stream
...
@@ -470,14 +474,21 @@ int nghttp2_session_reprioritize_stream
/* We have to update weight after removing stream from tree */
/* We have to update weight after removing stream from tree */
stream
->
weight
=
pri_spec
->
weight
;
stream
->
weight
=
pri_spec
->
weight
;
rv
=
nghttp2_stream_dep_make_root
(
stream
,
&
session
->
ob_pq
);
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
);
}
else
{
rv
=
nghttp2_stream_dep_make_root
(
stream
,
&
session
->
ob_pq
);
}
return
rv
;
return
rv
;
}
}
dep_stream
=
nghttp2_session_get_stream_raw
(
session
,
pri_spec
->
stream_id
);
dep_stream
=
nghttp2_session_get_stream_raw
(
session
,
pri_spec
->
stream_id
);
if
(
dep_stream
==
NULL
)
{
if
(
!
dep_stream
||
!
nghttp2_stream_in_dep_tree
(
dep_stream
)
)
{
return
0
;
return
0
;
}
}
...
@@ -711,7 +722,7 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
...
@@ -711,7 +722,7 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
}
}
nghttp2_stream_init
(
stream
,
stream_id
,
flags
,
initial_state
,
nghttp2_stream_init
(
stream
,
stream_id
,
flags
,
initial_state
,
pri_spec
->
weight
,
pri_spec
->
weight
,
&
session
->
roots
,
session
->
remote_settings
session
->
remote_settings
[
NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE
],
[
NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE
],
session
->
local_settings
session
->
local_settings
...
@@ -747,9 +758,29 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
...
@@ -747,9 +758,29 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
return
stream
;
return
stream
;
}
}
if
(
pri_spec
->
stream_id
==
0
)
{
++
session
->
roots
.
num_streams
;
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
);
/* Since no dpri is changed in dependency tree, the above
function call never fail. */
assert
(
rv
==
0
);
}
else
{
nghttp2_stream_roots_add
(
&
session
->
roots
,
stream
);
}
return
stream
;
}
dep_stream
=
nghttp2_session_get_stream_raw
(
session
,
pri_spec
->
stream_id
);
dep_stream
=
nghttp2_session_get_stream_raw
(
session
,
pri_spec
->
stream_id
);
if
(
!
dep_stream
)
{
/* If dep_stream is not part of dependency tree, we don't use it. */
if
(
!
dep_stream
||
!
nghttp2_stream_in_dep_tree
(
dep_stream
))
{
return
stream
;
return
stream
;
}
}
...
@@ -831,7 +862,9 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
...
@@ -831,7 +862,9 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
/* Closes both directions just in case they are not closed yet */
/* Closes both directions just in case they are not closed yet */
stream
->
flags
|=
NGHTTP2_STREAM_FLAG_CLOSED
;
stream
->
flags
|=
NGHTTP2_STREAM_FLAG_CLOSED
;
if
(
session
->
server
&&
!
nghttp2_session_is_my_stream_id
(
session
,
stream_id
))
{
if
(
session
->
server
&&
nghttp2_stream_in_dep_tree
(
stream
)
&&
!
nghttp2_session_is_my_stream_id
(
session
,
stream_id
))
{
/* On server side, retain incoming stream object at most
/* On server side, retain incoming stream object at most
MAX_CONCURRENT_STREAMS combined with the current active streams
MAX_CONCURRENT_STREAMS combined with the current active streams
to make dependency tree work better. */
to make dependency tree work better. */
...
...
lib/nghttp2_session.h
View file @
aa4d43f3
...
@@ -117,6 +117,7 @@ typedef enum {
...
@@ -117,6 +117,7 @@ typedef enum {
struct
nghttp2_session
{
struct
nghttp2_session
{
nghttp2_map
/* <nghttp2_stream*> */
streams
;
nghttp2_map
/* <nghttp2_stream*> */
streams
;
nghttp2_stream_roots
roots
;
/* Queue for outbound frames other than stream-creating HEADERS */
/* Queue for outbound frames other than stream-creating HEADERS */
nghttp2_pq
/* <nghttp2_outbound_item*> */
ob_pq
;
nghttp2_pq
/* <nghttp2_outbound_item*> */
ob_pq
;
/* Queue for outbound stream-creating HEADERS frame */
/* Queue for outbound stream-creating HEADERS frame */
...
...
lib/nghttp2_stream.c
View file @
aa4d43f3
...
@@ -33,6 +33,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
...
@@ -33,6 +33,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t
flags
,
uint8_t
flags
,
nghttp2_stream_state
initial_state
,
nghttp2_stream_state
initial_state
,
int32_t
weight
,
int32_t
weight
,
nghttp2_stream_roots
*
roots
,
int32_t
remote_initial_window_size
,
int32_t
remote_initial_window_size
,
int32_t
local_initial_window_size
,
int32_t
local_initial_window_size
,
void
*
stream_user_data
)
void
*
stream_user_data
)
...
@@ -61,6 +62,10 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
...
@@ -61,6 +62,10 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream
->
weight
=
weight
;
stream
->
weight
=
weight
;
stream
->
effective_weight
=
stream
->
weight
;
stream
->
effective_weight
=
stream
->
weight
;
stream
->
sum_dep_weight
=
0
;
stream
->
sum_dep_weight
=
0
;
stream
->
roots
=
roots
;
stream
->
root_prev
=
NULL
;
stream
->
root_next
=
NULL
;
}
}
void
nghttp2_stream_free
(
nghttp2_stream
*
stream
)
void
nghttp2_stream_free
(
nghttp2_stream
*
stream
)
...
@@ -474,6 +479,8 @@ void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
...
@@ -474,6 +479,8 @@ void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
stream_update_dep_length
(
dep_stream
,
1
);
stream_update_dep_length
(
dep_stream
,
1
);
stream_update_dep_effective_weight
(
dep_stream
);
stream_update_dep_effective_weight
(
dep_stream
);
++
stream
->
roots
->
num_streams
;
}
}
void
nghttp2_stream_dep_add
(
nghttp2_stream
*
dep_stream
,
void
nghttp2_stream_dep_add
(
nghttp2_stream
*
dep_stream
,
...
@@ -502,6 +509,8 @@ void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
...
@@ -502,6 +509,8 @@ void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
}
}
stream_update_dep_effective_weight
(
dep_stream
);
stream_update_dep_effective_weight
(
dep_stream
);
++
stream
->
roots
->
num_streams
;
}
}
void
nghttp2_stream_dep_remove
(
nghttp2_stream
*
stream
)
void
nghttp2_stream_dep_remove
(
nghttp2_stream
*
stream
)
...
@@ -568,6 +577,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
...
@@ -568,6 +577,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
dep_next
=
NULL
;
dep_next
=
NULL
;
}
}
}
else
{
}
else
{
nghttp2_stream_roots_remove
(
stream
->
roots
,
stream
);
dep_next
=
NULL
;
dep_next
=
NULL
;
/* stream is a root of tree. Removing stream makes its
/* stream is a root of tree. Removing stream makes its
...
@@ -583,6 +594,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
...
@@ -583,6 +594,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
/* We already distributed weight of |stream| to this. */
/* We already distributed weight of |stream| to this. */
si
->
effective_weight
=
si
->
weight
;
si
->
effective_weight
=
si
->
weight
;
nghttp2_stream_roots_add
(
si
->
roots
,
si
);
si
=
next
;
si
=
next
;
}
}
}
}
...
@@ -606,6 +619,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
...
@@ -606,6 +619,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
stream
->
dep_next
=
NULL
;
stream
->
dep_next
=
NULL
;
stream
->
sib_prev
=
NULL
;
stream
->
sib_prev
=
NULL
;
stream
->
sib_next
=
NULL
;
stream
->
sib_next
=
NULL
;
--
stream
->
roots
->
num_streams
;
}
}
int
nghttp2_stream_dep_insert_subtree
(
nghttp2_stream
*
dep_stream
,
int
nghttp2_stream_dep_insert_subtree
(
nghttp2_stream
*
dep_stream
,
...
@@ -748,6 +763,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream)
...
@@ -748,6 +763,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream)
}
}
}
else
{
}
else
{
nghttp2_stream_roots_remove
(
stream
->
roots
,
stream
);
dep_prev
=
NULL
;
dep_prev
=
NULL
;
}
}
...
@@ -771,6 +788,8 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
...
@@ -771,6 +788,8 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
DEBUGF
(
fprintf
(
stderr
,
"stream: dep_make_root stream(%p)=%d
\n
"
,
DEBUGF
(
fprintf
(
stderr
,
"stream: dep_make_root stream(%p)=%d
\n
"
,
stream
,
stream
->
stream_id
));
stream
,
stream
->
stream_id
));
nghttp2_stream_roots_add
(
stream
->
roots
,
stream
);
stream_update_dep_set_rest
(
stream
);
stream_update_dep_set_rest
(
stream
);
stream
->
effective_weight
=
stream
->
weight
;
stream
->
effective_weight
=
stream
->
weight
;
...
@@ -785,3 +804,141 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
...
@@ -785,3 +804,141 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
return
0
;
return
0
;
}
}
int
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
nghttp2_stream
*
stream
,
nghttp2_pq
*
pq
)
{
nghttp2_stream
*
first
,
*
si
;
DEBUGF
(
fprintf
(
stderr
,
"stream: ALL YOUR STREAM ARE BELONG TO US "
"stream(%p)=%d
\n
"
,
stream
,
stream
->
stream_id
));
first
=
stream
->
roots
->
head
;
/* stream must not be include in stream->roots->head list */
assert
(
first
!=
stream
);
if
(
first
)
{
nghttp2_stream
*
prev
;
prev
=
first
;
DEBUGF
(
fprintf
(
stderr
,
"stream: root stream(%p)=%d
\n
"
,
first
,
first
->
stream_id
));
stream
->
sum_dep_weight
+=
first
->
weight
;
stream
->
num_substreams
+=
first
->
num_substreams
;
for
(
si
=
first
->
root_next
;
si
;
si
=
si
->
root_next
)
{
assert
(
si
!=
stream
);
DEBUGF
(
fprintf
(
stderr
,
"stream: root stream(%p)=%d
\n
"
,
si
,
si
->
stream_id
));
fprintf
(
stderr
,
"w=%d, sum=%d
\n
"
,
si
->
weight
,
stream
->
sum_dep_weight
);
stream
->
sum_dep_weight
+=
si
->
weight
;
stream
->
num_substreams
+=
si
->
num_substreams
;
si
->
sib_prev
=
prev
;
prev
->
sib_next
=
si
;
prev
=
si
;
}
if
(
stream
->
dep_next
)
{
nghttp2_stream
*
last_sib
;
last_sib
=
stream_last_sib
(
stream
->
dep_next
);
last_sib
->
sib_next
=
first
;
first
->
sib_prev
=
last_sib
;
}
else
{
stream
->
dep_next
=
first
;
first
->
dep_prev
=
stream
;
}
}
nghttp2_stream_roots_remove_all
(
stream
->
roots
);
return
nghttp2_stream_dep_make_root
(
stream
,
pq
);
}
int
nghttp2_stream_in_dep_tree
(
nghttp2_stream
*
stream
)
{
return
stream
->
dep_prev
||
stream
->
dep_next
||
stream
->
sib_prev
||
stream
->
sib_next
||
stream
->
root_next
||
stream
->
root_prev
||
stream
->
roots
->
head
==
stream
;
}
void
nghttp2_stream_roots_init
(
nghttp2_stream_roots
*
roots
)
{
roots
->
head
=
NULL
;
roots
->
num_streams
=
0
;
}
void
nghttp2_stream_roots_free
(
nghttp2_stream_roots
*
roots
)
{}
void
nghttp2_stream_roots_add
(
nghttp2_stream_roots
*
roots
,
nghttp2_stream
*
stream
)
{
if
(
roots
->
head
)
{
nghttp2_stream
*
si
;
for
(
si
=
roots
->
head
;
si
;
si
=
si
->
root_next
)
{
if
(
si
==
stream
)
{
assert
(
0
);
}
}
stream
->
root_next
=
roots
->
head
;
roots
->
head
->
root_prev
=
stream
;
}
roots
->
head
=
stream
;
}
void
nghttp2_stream_roots_remove
(
nghttp2_stream_roots
*
roots
,
nghttp2_stream
*
stream
)
{
nghttp2_stream
*
root_prev
,
*
root_next
;
root_prev
=
stream
->
root_prev
;
root_next
=
stream
->
root_next
;
if
(
root_prev
)
{
root_prev
->
root_next
=
root_next
;
if
(
root_next
)
{
root_next
->
root_prev
=
root_prev
;
}
}
else
{
if
(
root_next
)
{
root_next
->
root_prev
=
NULL
;
}
roots
->
head
=
root_next
;
}
stream
->
root_prev
=
NULL
;
stream
->
root_next
=
NULL
;
}
void
nghttp2_stream_roots_remove_all
(
nghttp2_stream_roots
*
roots
)
{
nghttp2_stream
*
si
,
*
next
;
for
(
si
=
roots
->
head
;
si
;)
{
next
=
si
->
root_next
;
si
->
root_prev
=
NULL
;
si
->
root_next
=
NULL
;
si
=
next
;
}
roots
->
head
=
NULL
;
}
lib/nghttp2_stream.h
View file @
aa4d43f3
...
@@ -102,6 +102,10 @@ typedef enum {
...
@@ -102,6 +102,10 @@ typedef enum {
NGHTTP2_STREAM_DPRI_REST
=
0x04
NGHTTP2_STREAM_DPRI_REST
=
0x04
}
nghttp2_stream_dpri
;
}
nghttp2_stream_dpri
;
struct
nghttp2_stream_roots
;
typedef
struct
nghttp2_stream_roots
nghttp2_stream_roots
;
struct
nghttp2_stream
;
struct
nghttp2_stream
;
typedef
struct
nghttp2_stream
nghttp2_stream
;
typedef
struct
nghttp2_stream
nghttp2_stream
;
...
@@ -118,11 +122,17 @@ struct nghttp2_stream {
...
@@ -118,11 +122,17 @@ struct nghttp2_stream {
dep_prev and sib_prev are NULL. */
dep_prev and sib_prev are NULL. */
nghttp2_stream
*
dep_prev
,
*
dep_next
;
nghttp2_stream
*
dep_prev
,
*
dep_next
;
nghttp2_stream
*
sib_prev
,
*
sib_next
;
nghttp2_stream
*
sib_prev
,
*
sib_next
;
/* pointers to track dependency tree root streams. This is
doubly-linked list and first element is pointed by
roots->head. */
nghttp2_stream
*
root_prev
,
*
root_next
;
/* When stream is kept after closure, it may be kept in single
/* When stream is kept after closure, it may be kept in single
linked list pointed by nghttp2_session closed_stream_head.
linked list pointed by nghttp2_session closed_stream_head.
closed_next points to the next stream object if it is the element
closed_next points to the next stream object if it is the element
of the list. */
of the list. */
nghttp2_stream
*
closed_next
;
nghttp2_stream
*
closed_next
;
/* pointer to roots, which tracks dependency tree roots */
nghttp2_stream_roots
*
roots
;
/* The arbitrary data provided by user for this stream. */
/* The arbitrary data provided by user for this stream. */
void
*
stream_user_data
;
void
*
stream_user_data
;
/* DATA frame item */
/* DATA frame item */
...
@@ -165,6 +175,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
...
@@ -165,6 +175,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t
flags
,
uint8_t
flags
,
nghttp2_stream_state
initial_state
,
nghttp2_stream_state
initial_state
,
int32_t
weight
,
int32_t
weight
,
nghttp2_stream_roots
*
roots
,
int32_t
remote_initial_window_size
,
int32_t
remote_initial_window_size
,
int32_t
local_initial_window_size
,
int32_t
local_initial_window_size
,
void
*
stream_user_data
);
void
*
stream_user_data
);
...
@@ -380,4 +391,40 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
...
@@ -380,4 +391,40 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
*/
*/
int
nghttp2_stream_dep_make_root
(
nghttp2_stream
*
stream
,
nghttp2_pq
*
pq
);
int
nghttp2_stream_dep_make_root
(
nghttp2_stream
*
stream
,
nghttp2_pq
*
pq
);
/*
* Makes the |stream| as root and all existing root streams become
* direct children of |stream|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
nghttp2_stream
*
stream
,
nghttp2_pq
*
pq
);
/*
* Returns nonzero if |stream| is in any dependency tree.
*/
int
nghttp2_stream_in_dep_tree
(
nghttp2_stream
*
stream
);
struct
nghttp2_stream_roots
{
nghttp2_stream
*
head
;
int32_t
num_streams
;
};
void
nghttp2_stream_roots_init
(
nghttp2_stream_roots
*
roots
);
void
nghttp2_stream_roots_free
(
nghttp2_stream_roots
*
roots
);
void
nghttp2_stream_roots_add
(
nghttp2_stream_roots
*
roots
,
nghttp2_stream
*
stream
);
void
nghttp2_stream_roots_remove
(
nghttp2_stream_roots
*
roots
,
nghttp2_stream
*
stream
);
void
nghttp2_stream_roots_remove_all
(
nghttp2_stream_roots
*
roots
);
#endif
/* NGHTTP2_STREAM */
#endif
/* NGHTTP2_STREAM */
lib/nghttp2_submit.c
View file @
aa4d43f3
...
@@ -103,10 +103,6 @@ static int nghttp2_submit_headers_shared
...
@@ -103,10 +103,6 @@ static int nghttp2_submit_headers_shared
static
void
adjust_priority_spec_weight
(
nghttp2_priority_spec
*
pri_spec
)
static
void
adjust_priority_spec_weight
(
nghttp2_priority_spec
*
pri_spec
)
{
{
if
(
pri_spec
->
stream_id
==
0
)
{
pri_spec
->
exclusive
=
0
;
}
if
(
pri_spec
->
weight
<
NGHTTP2_MIN_WEIGHT
)
{
if
(
pri_spec
->
weight
<
NGHTTP2_MIN_WEIGHT
)
{
pri_spec
->
weight
=
NGHTTP2_MIN_WEIGHT
;
pri_spec
->
weight
=
NGHTTP2_MIN_WEIGHT
;
}
else
if
(
pri_spec
->
weight
>
NGHTTP2_MAX_WEIGHT
)
{
}
else
if
(
pri_spec
->
weight
>
NGHTTP2_MAX_WEIGHT
)
{
...
...
tests/main.c
View file @
aa4d43f3
...
@@ -222,6 +222,8 @@ int main(int argc, char* argv[])
...
@@ -222,6 +222,8 @@ int main(int argc, char* argv[])
test_nghttp2_session_stream_dep_add_subtree
)
||
test_nghttp2_session_stream_dep_add_subtree
)
||
!
CU_add_test
(
pSuite
,
"session_stream_dep_remove_subtree"
,
!
CU_add_test
(
pSuite
,
"session_stream_dep_remove_subtree"
,
test_nghttp2_session_stream_dep_remove_subtree
)
||
test_nghttp2_session_stream_dep_remove_subtree
)
||
!
CU_add_test
(
pSuite
,
"session_stream_dep_all_your_stream_are_belong_to_us"
,
test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us
)
||
!
CU_add_test
(
pSuite
,
"session_stream_attach_data"
,
!
CU_add_test
(
pSuite
,
"session_stream_attach_data"
,
test_nghttp2_session_stream_attach_data
)
||
test_nghttp2_session_stream_attach_data
)
||
!
CU_add_test
(
pSuite
,
"session_stream_attach_data_subtree"
,
!
CU_add_test
(
pSuite
,
"session_stream_attach_data_subtree"
,
...
...
tests/nghttp2_session_test.c
View file @
aa4d43f3
...
@@ -4873,6 +4873,10 @@ void test_nghttp2_session_stream_dep_add(void)
...
@@ -4873,6 +4873,10 @@ void test_nghttp2_session_stream_dep_add(void)
check_stream_dep_sib
(
c
,
NULL
,
d
,
b
,
NULL
);
check_stream_dep_sib
(
c
,
NULL
,
d
,
b
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
CU_ASSERT
(
4
==
session
->
roots
.
num_streams
);
CU_ASSERT
(
a
==
session
->
roots
.
head
);
CU_ASSERT
(
NULL
==
a
->
root_next
);
e
=
open_stream_with_dep_excl
(
session
,
9
,
a
);
e
=
open_stream_with_dep_excl
(
session
,
9
,
a
);
/* a
/* a
...
@@ -4902,6 +4906,10 @@ void test_nghttp2_session_stream_dep_add(void)
...
@@ -4902,6 +4906,10 @@ void test_nghttp2_session_stream_dep_add(void)
check_stream_dep_sib
(
c
,
NULL
,
d
,
b
,
NULL
);
check_stream_dep_sib
(
c
,
NULL
,
d
,
b
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
CU_ASSERT
(
5
==
session
->
roots
.
num_streams
);
CU_ASSERT
(
a
==
session
->
roots
.
head
);
CU_ASSERT
(
NULL
==
a
->
root_next
);
nghttp2_session_del
(
session
);
nghttp2_session_del
(
session
);
}
}
...
@@ -4951,6 +4959,11 @@ void test_nghttp2_session_stream_dep_remove(void)
...
@@ -4951,6 +4959,11 @@ void test_nghttp2_session_stream_dep_remove(void)
check_stream_dep_sib
(
c
,
NULL
,
d
,
NULL
,
NULL
);
check_stream_dep_sib
(
c
,
NULL
,
d
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
CU_ASSERT
(
3
==
session
->
roots
.
num_streams
);
CU_ASSERT
(
c
==
session
->
roots
.
head
);
CU_ASSERT
(
b
==
c
->
root_next
);
CU_ASSERT
(
NULL
==
b
->
root_next
);
nghttp2_session_del
(
session
);
nghttp2_session_del
(
session
);
/* Remove left most stream */
/* Remove left most stream */
...
@@ -4993,6 +5006,10 @@ void test_nghttp2_session_stream_dep_remove(void)
...
@@ -4993,6 +5006,10 @@ void test_nghttp2_session_stream_dep_remove(void)
check_stream_dep_sib
(
c
,
a
,
d
,
NULL
,
NULL
);
check_stream_dep_sib
(
c
,
a
,
d
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
NULL
);
CU_ASSERT
(
3
==
session
->
roots
.
num_streams
);
CU_ASSERT
(
a
==
session
->
roots
.
head
);
CU_ASSERT
(
NULL
==
a
->
root_next
);
nghttp2_session_del
(
session
);
nghttp2_session_del
(
session
);
/* Remove right most stream */
/* Remove right most stream */
...
@@ -5348,6 +5365,131 @@ void test_nghttp2_session_stream_dep_remove_subtree(void)
...
@@ -5348,6 +5365,131 @@ void test_nghttp2_session_stream_dep_remove_subtree(void)
nghttp2_session_del
(
session
);
nghttp2_session_del
(
session
);
}
}
void
test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us
(
void
)
{
nghttp2_session
*
session
;
nghttp2_session_callbacks
callbacks
;
nghttp2_stream
*
a
,
*
b
,
*
c
,
*
d
;
memset
(
&
callbacks
,
0
,
sizeof
(
callbacks
));
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
NULL
);
a
=
open_stream
(
session
,
1
);
b
=
open_stream_with_dep
(
session
,
3
,
a
);
c
=
open_stream
(
session
,
5
);
/* a c
* |
* b
*/
nghttp2_stream_dep_remove_subtree
(
c
);
CU_ASSERT
(
0
==
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
c
,
&
session
->
ob_pq
));
/*
* c
* |
* a
* |
* b
*/
CU_ASSERT
(
3
==
c
->
num_substreams
);
CU_ASSERT
(
2
==
a
->
num_substreams
);
CU_ASSERT
(
1
==
b
->
num_substreams
);
CU_ASSERT
(
NGHTTP2_DEFAULT_WEIGHT
==
c
->
sum_dep_weight
);
CU_ASSERT
(
NGHTTP2_DEFAULT_WEIGHT
==
a
->
sum_dep_weight
);
CU_ASSERT
(
0
==
b
->
sum_dep_weight
);
check_stream_dep_sib
(
c
,
NULL
,
a
,
NULL
,
NULL
);
check_stream_dep_sib
(
a
,
c
,
b
,
NULL
,
NULL
);
check_stream_dep_sib
(
b
,
a
,
NULL
,
NULL
,
NULL
);
nghttp2_session_del
(
session
);
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
NULL
);
a
=
open_stream
(
session
,
1
);
b
=
open_stream
(
session
,
3
);
c
=
open_stream
(
session
,
5
);
/*
* a b c
*/
nghttp2_stream_dep_remove_subtree
(
c
);
CU_ASSERT
(
0
==
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
c
,
&
session
->
ob_pq
));
/*
* c
* |
* b--a
*/
CU_ASSERT
(
3
==
c
->
num_substreams
);
CU_ASSERT
(
1
==
a
->
num_substreams
);
CU_ASSERT
(
1
==
b
->
num_substreams
);
CU_ASSERT
(
NGHTTP2_DEFAULT_WEIGHT
*
2
==
c
->
sum_dep_weight
);
CU_ASSERT
(
0
==
b
->
sum_dep_weight
);
CU_ASSERT
(
0
==
a
->
sum_dep_weight
);
check_stream_dep_sib
(
c
,
NULL
,
b
,
NULL
,
NULL
);
check_stream_dep_sib
(
b
,
c
,
NULL
,
NULL
,
a
);
check_stream_dep_sib
(
a
,
NULL
,
NULL
,
b
,
NULL
);
nghttp2_session_del
(
session
);
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
NULL
);
a
=
open_stream
(
session
,
1
);
b
=
open_stream_with_dep
(
session
,
3
,
a
);
c
=
open_stream
(
session
,
5
);
d
=
open_stream_with_dep
(
session
,
7
,
c
);
/* a c
* | |
* b d
*/
nghttp2_stream_dep_remove_subtree
(
c
);
CU_ASSERT
(
0
==
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
c
,
&
session
->
ob_pq
));
/*
* c
* |
* d--a
* |
* b
*/
CU_ASSERT
(
4
==
c
->
num_substreams
);
CU_ASSERT
(
1
==
d
->
num_substreams
);
CU_ASSERT
(
2
==
a
->
num_substreams
);
CU_ASSERT
(
1
==
b
->
num_substreams
);
CU_ASSERT
(
NGHTTP2_DEFAULT_WEIGHT
*
2
==
c
->
sum_dep_weight
);
CU_ASSERT
(
0
==
d
->
sum_dep_weight
);
CU_ASSERT
(
NGHTTP2_DEFAULT_WEIGHT
==
a
->
sum_dep_weight
);
CU_ASSERT
(
0
==
b
->
sum_dep_weight
);
check_stream_dep_sib
(
c
,
NULL
,
d
,
NULL
,
NULL
);
check_stream_dep_sib
(
d
,
c
,
NULL
,
NULL
,
a
);
check_stream_dep_sib
(
a
,
NULL
,
b
,
d
,
NULL
);
check_stream_dep_sib
(
b
,
a
,
NULL
,
NULL
,
NULL
);
nghttp2_session_del
(
session
);
}
static
nghttp2_outbound_item
*
create_data_ob_item
(
void
)
static
nghttp2_outbound_item
*
create_data_ob_item
(
void
)
{
{
nghttp2_outbound_item
*
item
;
nghttp2_outbound_item
*
item
;
...
@@ -5488,6 +5630,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
...
@@ -5488,6 +5630,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Insert subtree e under a */
/* 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
);
/*
/*
...
@@ -5570,6 +5713,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
...
@@ -5570,6 +5713,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Add subtree c to a */
/* 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
);
/*
/*
...
@@ -5589,6 +5733,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
...
@@ -5589,6 +5733,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
/* Insert b under a */
/* 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
);
/*
/*
...
@@ -5608,21 +5753,10 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
...
@@ -5608,21 +5753,10 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
CU_ASSERT
(
NGHTTP2_STREAM_DPRI_REST
==
e
->
dpri
);
CU_ASSERT
(
NGHTTP2_STREAM_DPRI_REST
==
e
->
dpri
);
CU_ASSERT
(
NGHTTP2_STREAM_DPRI_NO_DATA
==
f
->
dpri
);
CU_ASSERT
(
NGHTTP2_STREAM_DPRI_NO_DATA
==
f
->
dpri
);
nghttp2_stream_dep_make_root
(
a
,
&
session
->
ob_pq
);
/*
* a
* |
* b
* |
* e--c
* | |
* f d
*/
/* Remove subtree b */
/* Remove subtree b */
nghttp2_stream_dep_remove_subtree
(
b
);
nghttp2_stream_dep_remove_subtree
(
b
);
nghttp2_stream_dep_make_root
(
b
,
&
session
->
ob_pq
);
/*
/*
* b a
* b a
...
@@ -5870,6 +6004,58 @@ void test_nghttp2_session_stream_dep_effective_weight(void)
...
@@ -5870,6 +6004,58 @@ void test_nghttp2_session_stream_dep_effective_weight(void)
CU_ASSERT
(
16
*
4
/
20
==
d
->
effective_weight
);
CU_ASSERT
(
16
*
4
/
20
==
d
->
effective_weight
);
nghttp2_session_del
(
session
);
nghttp2_session_del
(
session
);
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
NULL
);
a
=
open_stream
(
session
,
1
);
b
=
open_stream_with_dep_weight
(
session
,
3
,
8
,
a
);
c
=
open_stream_with_dep_weight
(
session
,
5
,
4
,
a
);
d
=
open_stream_with_dep_weight
(
session
,
7
,
1
,
c
);
e
=
open_stream
(
session
,
9
);
f
=
open_stream_with_dep_weight
(
session
,
11
,
12
,
e
);
/* a e
* | |
* b--c f
* |
* d
*/
CU_ASSERT
(
e
->
roots
->
head
==
e
);
CU_ASSERT
(
a
==
e
->
root_next
);
/* Insert e under stream 0 */
nghttp2_stream_dep_remove_subtree
(
e
);
CU_ASSERT
(
a
==
e
->
roots
->
head
);
CU_ASSERT
(
0
==
nghttp2_stream_dep_all_your_stream_are_belong_to_us
(
e
,
&
session
->
ob_pq
));
/* e
* |
* f--a
* |
* b--c
* |
* d
*/
CU_ASSERT
(
6
==
e
->
num_substreams
);
CU_ASSERT
(
28
==
e
->
sum_dep_weight
);
CU_ASSERT
(
16
==
e
->
effective_weight
);
CU_ASSERT
(
16
*
16
/
28
==
a
->
effective_weight
);
CU_ASSERT
(
16
*
12
/
28
==
f
->
effective_weight
);
CU_ASSERT
((
16
*
16
/
28
)
*
8
/
12
==
b
->
effective_weight
);
CU_ASSERT
((
16
*
16
/
28
)
*
4
/
12
==
c
->
effective_weight
);
CU_ASSERT
((
16
*
16
/
28
)
*
4
/
12
==
d
->
effective_weight
);
nghttp2_session_del
(
session
);
}
}
void
test_nghttp2_session_keep_closed_stream
(
void
)
void
test_nghttp2_session_keep_closed_stream
(
void
)
...
...
tests/nghttp2_session_test.h
View file @
aa4d43f3
...
@@ -103,6 +103,7 @@ void test_nghttp2_session_stream_dep_add(void);
...
@@ -103,6 +103,7 @@ void test_nghttp2_session_stream_dep_add(void);
void
test_nghttp2_session_stream_dep_remove
(
void
);
void
test_nghttp2_session_stream_dep_remove
(
void
);
void
test_nghttp2_session_stream_dep_add_subtree
(
void
);
void
test_nghttp2_session_stream_dep_add_subtree
(
void
);
void
test_nghttp2_session_stream_dep_remove_subtree
(
void
);
void
test_nghttp2_session_stream_dep_remove_subtree
(
void
);
void
test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us
(
void
);
void
test_nghttp2_session_stream_attach_data
(
void
);
void
test_nghttp2_session_stream_attach_data
(
void
);
void
test_nghttp2_session_stream_attach_data_subtree
(
void
);
void
test_nghttp2_session_stream_attach_data_subtree
(
void
);
void
test_nghttp2_session_stream_dep_effective_weight
(
void
);
void
test_nghttp2_session_stream_dep_effective_weight
(
void
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment