Keep incoming streams only at server side

We should only keep incoming closed streams because we only keep at
most max concurrent streams, which only applied to incoming streams.
This commit is contained in:
Tatsuhiro Tsujikawa 2015-12-03 22:48:41 +09:00
parent 2288ee8060
commit 93d8636fb0
3 changed files with 31 additions and 8 deletions

View File

@ -1023,6 +1023,7 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
int rv;
nghttp2_stream *stream;
nghttp2_mem *mem;
int is_my_stream_id;
mem = &session->mem;
stream = nghttp2_session_get_stream(session, stream_id);
@ -1070,14 +1071,16 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
}
}
is_my_stream_id = nghttp2_session_is_my_stream_id(session, stream_id);
/* pushed streams which is not opened yet is not counted toward max
concurrent limits */
if ((stream->flags & NGHTTP2_STREAM_FLAG_PUSH)) {
if (!nghttp2_session_is_my_stream_id(session, stream_id)) {
if (!is_my_stream_id) {
--session->num_incoming_reserved_streams;
}
} else {
if (nghttp2_session_is_my_stream_id(session, stream_id)) {
if (is_my_stream_id) {
--session->num_outgoing_streams;
} else {
--session->num_incoming_streams;
@ -1087,7 +1090,8 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
/* Closes both directions just in case they are not closed yet */
stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED;
if (session->server && nghttp2_stream_in_dep_tree(stream)) {
if (session->server && !is_my_stream_id &&
nghttp2_stream_in_dep_tree(stream)) {
/* On server side, retain stream at most MAX_CONCURRENT_STREAMS
combined with the current active incoming streams to make
dependency tree work better. */

View File

@ -190,11 +190,13 @@ struct nghttp2_session {
updated when one frame was written. */
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. */
/* Points to the latest incoming closed stream. NULL if there is no
closed stream. Only used when session is initialized as
server. */
nghttp2_stream *closed_stream_head;
/* Points to the oldest closed stream. NULL if there is no closed
stream. Only used when session is initialized as server. */
/* Points to the oldest incoming closed stream. NULL if there is no
closed stream. Only used when session is initialized as
server. */
nghttp2_stream *closed_stream_tail;
/* Points to the latest idle stream. NULL if there is no idle
stream. Only used when session is initialized as server .*/

View File

@ -7378,7 +7378,8 @@ void test_nghttp2_session_stream_get_state(void) {
stream = nghttp2_session_find_stream(session, 2);
CU_ASSERT(NGHTTP2_STREAM_STATE_CLOSED == nghttp2_stream_get_state(stream));
/* At server, pushed stream object is not retained after closed */
CU_ASSERT(NULL == stream);
/* Push stream 4 associated to stream 5 */
rv = nghttp2_submit_push_promise(session, NGHTTP2_FLAG_NONE, 5, reqnv,
@ -7599,6 +7600,22 @@ void test_nghttp2_session_keep_closed_stream(void) {
CU_ASSERT(NULL == session->closed_stream_tail);
CU_ASSERT(NULL == session->closed_stream_head);
nghttp2_session_close_stream(session, 3, NGHTTP2_NO_ERROR);
CU_ASSERT(1 == session->num_closed_streams);
CU_ASSERT(3 == session->closed_stream_head->stream_id);
/* server initiated stream is not counted to max concurrent limit */
open_stream(session, 2);
CU_ASSERT(1 == session->num_closed_streams);
CU_ASSERT(3 == session->closed_stream_head->stream_id);
nghttp2_session_close_stream(session, 2, NGHTTP2_NO_ERROR);
CU_ASSERT(1 == session->num_closed_streams);
CU_ASSERT(3 == session->closed_stream_head->stream_id);
nghttp2_session_del(session);
}