Handle circular dependency

Handle the situation if a stream is told to depend on its descendant.
This is what
http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-5.3.3
says.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-04-24 23:44:34 +09:00
parent 853c9888d9
commit ee26469cd9
2 changed files with 8 additions and 6 deletions

View File

@ -492,14 +492,15 @@ int nghttp2_session_reprioritize_stream
return 0; return 0;
} }
/* Ignore priority request if resultant tree has cycle */
if(nghttp2_stream_dep_subtree_find(stream, dep_stream)) { if(nghttp2_stream_dep_subtree_find(stream, dep_stream)) {
DEBUGF(fprintf(stderr, DEBUGF(fprintf(stderr,
"stream: future cycle detected, dep_stream(%p)=%d " "stream: cycle detected, dep_stream(%p)=%d "
"stream(%p)=%d\n", "stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, dep_stream, dep_stream->stream_id,
stream, stream->stream_id)); stream, stream->stream_id));
return 0;
nghttp2_stream_dep_remove_subtree(dep_stream);
nghttp2_stream_dep_make_root(dep_stream, &session->ob_pq);
} }
nghttp2_stream_dep_remove_subtree(stream); nghttp2_stream_dep_remove_subtree(stream);

View File

@ -2586,13 +2586,14 @@ void test_nghttp2_session_reprioritize_stream(void)
CU_ASSERT(99 == stream->weight); CU_ASSERT(99 == stream->weight);
CU_ASSERT(dep_stream == stream->dep_prev); CU_ASSERT(dep_stream == stream->dep_prev);
/* Test circular dependency; must be ignored */ /* Test circular dependency; stream 1 is first removed and becomes
root. Then stream 3 depends on it. */
nghttp2_priority_spec_init(&pri_spec, 1, 1, 0); nghttp2_priority_spec_init(&pri_spec, 1, 1, 0);
nghttp2_session_reprioritize_stream(session, dep_stream, &pri_spec); nghttp2_session_reprioritize_stream(session, dep_stream, &pri_spec);
CU_ASSERT(16 == dep_stream->weight); CU_ASSERT(1 == dep_stream->weight);
CU_ASSERT(NULL == dep_stream->dep_prev); CU_ASSERT(stream == dep_stream->dep_prev);
nghttp2_session_del(session); nghttp2_session_del(session);
} }