diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index 9c580a3f..941dd84b 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -2062,8 +2062,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, * negative error codes: * * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` - * The stream does not exist; or no deferred data exist; or data - * was deferred by flow control. + * The stream does not exist; or no deferred data exist. * :enum:`NGHTTP2_ERR_NOMEM` * Out of memory. */ diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index f7ced8f1..182a34be 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -3275,12 +3275,12 @@ static int update_remote_initial_window_size_func /* If window size gets positive, push deferred DATA frame to outbound queue. */ - if(nghttp2_stream_check_deferred_by_flow_control(stream) && - stream->remote_window_size > 0 && - arg->session->remote_window_size > 0) { + if(stream->remote_window_size > 0 && + nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = nghttp2_stream_resume_deferred_data(stream, &arg->session->ob_da_pq, - arg->session->last_cycle); + rv = nghttp2_stream_resume_deferred_data + (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, + &arg->session->ob_da_pq, arg->session->last_cycle); if(nghttp2_is_fatal(rv)) { return rv; @@ -3899,8 +3899,9 @@ static int session_on_stream_window_update_received if(stream->remote_window_size > 0 && nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_da_pq, - session->last_cycle); + rv = nghttp2_stream_resume_deferred_data + (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_da_pq, + session->last_cycle); if(nghttp2_is_fatal(rv)) { return rv; @@ -5863,14 +5864,13 @@ int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) int rv; nghttp2_stream *stream; stream = nghttp2_session_get_stream(session, stream_id); - if(stream == NULL || - nghttp2_stream_check_deferred_by_flow_control(stream) || - !nghttp2_stream_check_deferred_data(stream)) { + if(stream == NULL || !nghttp2_stream_check_deferred_data(stream)) { return NGHTTP2_ERR_INVALID_ARGUMENT; } - rv = nghttp2_stream_resume_deferred_data(stream, &session->ob_da_pq, - session->last_cycle); + rv = nghttp2_stream_resume_deferred_data + (stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER, &session->ob_da_pq, + session->last_cycle); if(nghttp2_is_fatal(rv)) { return rv; diff --git a/lib/nghttp2_stream.c b/lib/nghttp2_stream.c index 713f99d2..f4d54e1b 100644 --- a/lib/nghttp2_stream.c +++ b/lib/nghttp2_stream.c @@ -383,15 +383,19 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, return stream_update_dep_on_detach_data(stream, pq, cycle); } -int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, +int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, uint8_t flags, nghttp2_pq *pq, uint64_t cycle) { assert(stream->data_item); - DEBUGF(fprintf(stderr, "stream: stream=%d resume data=%p\n", - stream->stream_id, stream->data_item)); + DEBUGF(fprintf(stderr, "stream: stream=%d resume data=%p flags=%02x\n", + stream->stream_id, stream->data_item, flags)); - stream->flags &= ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL; + stream->flags &= ~flags; + + if(stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { + return 0; + } return stream_update_dep_on_attach_data(stream, pq, cycle); } diff --git a/lib/nghttp2_stream.h b/lib/nghttp2_stream.h index 5b33dcf9..bc0648ef 100644 --- a/lib/nghttp2_stream.h +++ b/lib/nghttp2_stream.h @@ -216,12 +216,14 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, nghttp2_pq *pq, uint64_t cycle); /* - * Detaches deferred data in this stream and it is back to active - * state. The flags NGHTTP2_STREAM_FLAG_DEFERRED_USER and - * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL are cleared if they are - * set. + * Put back deferred data in this stream to active state. The |flags| + * are one or more of bitwise OR of the following values: + * NGHTTP2_STREAM_FLAG_DEFERRED_USER and + * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are + * cleared if they are set. So even if this function is called, if + * one of flag is still set, data does not become active. */ -int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, +int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, uint8_t flags, nghttp2_pq *pq, uint64_t cycle); /*