Reduce nghttp2_session_get_stream() call before sending frame

This commit is contained in:
Tatsuhiro Tsujikawa 2014-11-12 21:47:26 +09:00
parent b7c0576eb5
commit 24f83eef7c
1 changed files with 70 additions and 66 deletions

View File

@ -1209,7 +1209,8 @@ static int session_predicate_request_headers_send
/* /*
* This function checks HEADERS, which is the first frame from the * This function checks HEADERS, which is the first frame from the
* server, with the stream ID |stream_id| can be sent at this time. * server, with the |stream| can be sent at this time. The |stream|
* can be NULL.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
@ -1227,15 +1228,15 @@ static int session_predicate_request_headers_send
* The state of the stream is not valid. * The state of the stream is not valid.
*/ */
static int session_predicate_response_headers_send static int session_predicate_response_headers_send
(nghttp2_session *session, int32_t stream_id) (nghttp2_session *session, nghttp2_stream *stream)
{ {
nghttp2_stream *stream = nghttp2_session_get_stream(session, stream_id);
int rv; int rv;
rv = stream_predicate_for_send(stream); rv = stream_predicate_for_send(stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
if(nghttp2_session_is_my_stream_id(session, stream_id)) { assert(stream);
if(nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
return NGHTTP2_ERR_INVALID_STREAM_ID; return NGHTTP2_ERR_INVALID_STREAM_ID;
} }
if(stream->state == NGHTTP2_STREAM_OPENING) { if(stream->state == NGHTTP2_STREAM_OPENING) {
@ -1249,8 +1250,8 @@ static int session_predicate_response_headers_send
/* /*
* This function checks HEADERS for reserved stream can be sent. The * This function checks HEADERS for reserved stream can be sent. The
* stream |stream_id| must be reserved state and the |session| is * |stream| must be reserved state and the |session| is server side.
* server side. * The |stream| can be NULL.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* error codes: * error codes:
@ -1265,15 +1266,15 @@ static int session_predicate_response_headers_send
* RST_STREAM was queued for this stream. * RST_STREAM was queued for this stream.
*/ */
static int session_predicate_push_response_headers_send static int session_predicate_push_response_headers_send
(nghttp2_session *session, int32_t stream_id) (nghttp2_session *session, nghttp2_stream *stream)
{ {
nghttp2_stream *stream = nghttp2_session_get_stream(session, stream_id);
int rv; int rv;
/* TODO Should disallow HEADERS if GOAWAY has already been issued? */ /* TODO Should disallow HEADERS if GOAWAY has already been issued? */
rv = stream_predicate_for_send(stream); rv = stream_predicate_for_send(stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
assert(stream);
if(stream->state != NGHTTP2_STREAM_RESERVED) { if(stream->state != NGHTTP2_STREAM_RESERVED) {
return NGHTTP2_ERR_PROTO; return NGHTTP2_ERR_PROTO;
} }
@ -1284,8 +1285,8 @@ static int session_predicate_push_response_headers_send
} }
/* /*
* This function checks frames belongs to the stream |stream_id| can * This function checks frames belongs to the |stream| can be sent.
* be sent. * The |stream| can be NULL.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
@ -1301,15 +1302,15 @@ static int session_predicate_push_response_headers_send
* The state of the stream is not valid. * The state of the stream is not valid.
*/ */
static int session_predicate_stream_frame_send static int session_predicate_stream_frame_send
(nghttp2_session* session, int32_t stream_id) (nghttp2_session* session, nghttp2_stream *stream)
{ {
nghttp2_stream *stream = nghttp2_session_get_stream(session, stream_id);
int rv; int rv;
rv = stream_predicate_for_send(stream); rv = stream_predicate_for_send(stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
if(nghttp2_session_is_my_stream_id(session, stream_id)) { assert(stream);
if(nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
if(stream->state == NGHTTP2_STREAM_CLOSING) { if(stream->state == NGHTTP2_STREAM_CLOSING) {
return NGHTTP2_ERR_STREAM_CLOSING; return NGHTTP2_ERR_STREAM_CLOSING;
} }
@ -1326,18 +1327,18 @@ static int session_predicate_stream_frame_send
/* /*
* This function checks HEADERS, which is neither stream-opening nor * This function checks HEADERS, which is neither stream-opening nor
* first response header, with the stream ID |stream_id| can be sent * first response header, with the |stream| can be sent at this time.
* at this time. * The |stream| can be NULL.
*/ */
static int session_predicate_headers_send(nghttp2_session *session, static int session_predicate_headers_send(nghttp2_session *session,
int32_t stream_id) nghttp2_stream *stream)
{ {
return session_predicate_stream_frame_send(session, stream_id); return session_predicate_stream_frame_send(session, stream);
} }
/* /*
* This function checks PUSH_PROMISE frame |frame| with stream ID * This function checks PUSH_PROMISE frame |frame| with the |stream|
* |stream_id| can be sent at this time. * can be sent at this time. The |stream| can be NULL.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
@ -1359,22 +1360,26 @@ static int session_predicate_headers_send(nghttp2_session *session,
* The remote peer disabled reception of PUSH_PROMISE. * The remote peer disabled reception of PUSH_PROMISE.
*/ */
static int session_predicate_push_promise_send static int session_predicate_push_promise_send
(nghttp2_session *session, int32_t stream_id) (nghttp2_session *session, nghttp2_stream *stream)
{ {
int rv; int rv;
nghttp2_stream *stream;
if(!session->server) { if(!session->server) {
return NGHTTP2_ERR_PROTO; return NGHTTP2_ERR_PROTO;
} }
if(nghttp2_session_is_my_stream_id(session, stream_id)) {
/* The associated stream must be initiated by the remote peer */
return NGHTTP2_ERR_PROTO;
}
stream = nghttp2_session_get_stream(session, stream_id);
rv = stream_predicate_for_send(stream); rv = stream_predicate_for_send(stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
assert(stream);
if(nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
/* The associated stream must be initiated by the remote peer */
return NGHTTP2_ERR_PROTO;
}
if(session->remote_settings.enable_push == 0) { if(session->remote_settings.enable_push == 0) {
return NGHTTP2_ERR_PUSH_DISABLED; return NGHTTP2_ERR_PUSH_DISABLED;
} }
@ -1512,8 +1517,8 @@ static size_t nghttp2_session_next_data_read(nghttp2_session *session,
} }
/* /*
* This function checks DATA with the stream ID |stream_id| can be * This function checks DATA with the |stream| can be sent at this
* sent at this time. * time. The |stream| can be NULL.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
@ -1529,15 +1534,15 @@ static size_t nghttp2_session_next_data_read(nghttp2_session *session,
* The state of the stream is not valid. * The state of the stream is not valid.
*/ */
static int nghttp2_session_predicate_data_send(nghttp2_session *session, static int nghttp2_session_predicate_data_send(nghttp2_session *session,
int32_t stream_id) nghttp2_stream *stream)
{ {
nghttp2_stream *stream = nghttp2_session_get_stream(session, stream_id);
int rv; int rv;
rv = stream_predicate_for_send(stream); rv = stream_predicate_for_send(stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
if(nghttp2_session_is_my_stream_id(session, stream_id)) { assert(stream);
if(nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
/* Request body data */ /* Request body data */
/* If stream->state is NGHTTP2_STREAM_CLOSING, RST_STREAM was /* If stream->state is NGHTTP2_STREAM_CLOSING, RST_STREAM was
queued but not yet sent. In this case, we won't send DATA queued but not yet sent. In this case, we won't send DATA
@ -1689,29 +1694,27 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_NOMEM; return NGHTTP2_ERR_NOMEM;
} }
} else if(session_predicate_push_response_headers_send } else {
(session, frame->hd.stream_id) == 0) {
frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
if(aux_data->stream_user_data) {
nghttp2_stream *stream; nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if(session_predicate_push_response_headers_send
(session, stream) == 0) {
frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
if(aux_data->stream_user_data) {
stream->stream_user_data = aux_data->stream_user_data; stream->stream_user_data = aux_data->stream_user_data;
} }
} else if(session_predicate_response_headers_send } else if(session_predicate_response_headers_send
(session, frame->hd.stream_id) == 0) { (session, stream) == 0) {
frame->headers.cat = NGHTTP2_HCAT_RESPONSE; frame->headers.cat = NGHTTP2_HCAT_RESPONSE;
} else { } else {
frame->headers.cat = NGHTTP2_HCAT_HEADERS; frame->headers.cat = NGHTTP2_HCAT_HEADERS;
rv = session_predicate_headers_send(session, frame->hd.stream_id); rv = session_predicate_headers_send(session, stream);
if(rv != 0) { if(rv != 0) {
nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if(stream && stream->data_item == item) { if(stream && stream->data_item == item) {
int rv2; int rv2;
@ -1725,6 +1728,7 @@ static int session_prep_frame(nghttp2_session *session,
return rv; return rv;
} }
} }
}
framerv = nghttp2_frame_pack_headers(&session->aob.framebufs, framerv = nghttp2_frame_pack_headers(&session->aob.framebufs,
&frame->headers, &frame->headers,
@ -1812,11 +1816,15 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_FRAME_SIZE_ERROR; return NGHTTP2_ERR_FRAME_SIZE_ERROR;
} }
rv = session_predicate_push_promise_send(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
rv = session_predicate_push_promise_send(session, stream);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
assert(stream);
framerv = nghttp2_frame_pack_push_promise(&session->aob.framebufs, framerv = nghttp2_frame_pack_push_promise(&session->aob.framebufs,
&frame->push_promise, &frame->push_promise,
&session->hd_deflater); &session->hd_deflater);
@ -1828,9 +1836,6 @@ static int session_prep_frame(nghttp2_session *session,
return framerv; return framerv;
} }
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
assert(stream);
/* TODO It is unclear reserved stream dpeneds on associated /* TODO It is unclear reserved stream dpeneds on associated
stream with or without exclusive flag set */ stream with or without exclusive flag set */
nghttp2_priority_spec_init(&pri_spec, stream->stream_id, nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
@ -1906,7 +1911,7 @@ static int session_prep_frame(nghttp2_session *session,
assert(stream->data_item == item); assert(stream->data_item == item);
} }
rv = nghttp2_session_predicate_data_send(session, frame->hd.stream_id); rv = nghttp2_session_predicate_data_send(session, stream);
if(rv != 0) { if(rv != 0) {
if(stream) { if(stream) {
int rv2; int rv2;
@ -2377,8 +2382,7 @@ static int session_after_frame_sent(nghttp2_session *session)
/* If session is closed or RST_STREAM was queued, we won't send /* If session is closed or RST_STREAM was queued, we won't send
further data. */ further data. */
if(nghttp2_session_predicate_data_send(session, if(nghttp2_session_predicate_data_send(session, stream) != 0) {
frame->hd.stream_id) != 0) {
if(stream) { if(stream) {
rv = nghttp2_stream_detach_data(stream, session); rv = nghttp2_stream_detach_data(stream, session);