Fix bug that transfer stuck when stream marked as top is deferred
This commit is contained in:
parent
b671375abc
commit
ac2a8ef4a2
|
@ -1708,8 +1708,14 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
|
||||||
next_readmax = nghttp2_session_next_data_read(session, stream);
|
next_readmax = nghttp2_session_next_data_read(session, stream);
|
||||||
|
|
||||||
if(next_readmax == 0) {
|
if(next_readmax == 0) {
|
||||||
nghttp2_stream_defer_data(stream,
|
rv = nghttp2_stream_defer_data(stream,
|
||||||
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
|
||||||
|
&session->ob_pq);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
session->aob.item = NULL;
|
session->aob.item = NULL;
|
||||||
nghttp2_active_outbound_item_reset(&session->aob);
|
nghttp2_active_outbound_item_reset(&session->aob);
|
||||||
return NGHTTP2_ERR_DEFERRED;
|
return NGHTTP2_ERR_DEFERRED;
|
||||||
|
@ -1719,7 +1725,13 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
|
||||||
next_readmax,
|
next_readmax,
|
||||||
data_frame);
|
data_frame);
|
||||||
if(framerv == NGHTTP2_ERR_DEFERRED) {
|
if(framerv == NGHTTP2_ERR_DEFERRED) {
|
||||||
nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
|
rv = nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER,
|
||||||
|
&session->ob_pq);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
session->aob.item = NULL;
|
session->aob.item = NULL;
|
||||||
nghttp2_active_outbound_item_reset(&session->aob);
|
nghttp2_active_outbound_item_reset(&session->aob);
|
||||||
return NGHTTP2_ERR_DEFERRED;
|
return NGHTTP2_ERR_DEFERRED;
|
||||||
|
@ -2107,8 +2119,13 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
next_readmax = nghttp2_session_next_data_read(session, stream);
|
next_readmax = nghttp2_session_next_data_read(session, stream);
|
||||||
|
|
||||||
if(next_readmax == 0) {
|
if(next_readmax == 0) {
|
||||||
nghttp2_stream_defer_data(stream,
|
rv = nghttp2_stream_defer_data
|
||||||
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_pq);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
aob->item = NULL;
|
aob->item = NULL;
|
||||||
nghttp2_active_outbound_item_reset(aob);
|
nghttp2_active_outbound_item_reset(aob);
|
||||||
|
|
||||||
|
@ -2123,7 +2140,14 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
if(rv == NGHTTP2_ERR_DEFERRED) {
|
if(rv == NGHTTP2_ERR_DEFERRED) {
|
||||||
nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
|
rv = nghttp2_stream_defer_data(stream,
|
||||||
|
NGHTTP2_STREAM_FLAG_DEFERRED_USER,
|
||||||
|
&session->ob_pq);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
aob->item = NULL;
|
aob->item = NULL;
|
||||||
nghttp2_active_outbound_item_reset(aob);
|
nghttp2_active_outbound_item_reset(aob);
|
||||||
|
|
||||||
|
|
|
@ -359,11 +359,17 @@ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq)
|
||||||
return stream_update_dep_on_detach_data(stream, pq);
|
return stream_update_dep_on_detach_data(stream, pq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags)
|
int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
|
||||||
|
nghttp2_pq *pq)
|
||||||
{
|
{
|
||||||
assert(stream->data_item);
|
assert(stream->data_item);
|
||||||
|
|
||||||
|
DEBUGF(fprintf(stderr, "stream: stream=%d defer data=%p cause=%02x\n",
|
||||||
|
stream->stream_id, stream->data_item, flags));
|
||||||
|
|
||||||
stream->flags |= flags;
|
stream->flags |= flags;
|
||||||
|
|
||||||
|
return stream_update_dep_on_detach_data(stream, pq);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream,
|
int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream,
|
||||||
|
|
|
@ -185,8 +185,15 @@ void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag);
|
||||||
* bitwise OR of zero or more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and
|
* bitwise OR of zero or more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and
|
||||||
* NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL. The |flags| indicates
|
* NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL. The |flags| indicates
|
||||||
* the reason of this action.
|
* the reason of this action.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory
|
||||||
*/
|
*/
|
||||||
void nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags);
|
int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags,
|
||||||
|
nghttp2_pq *pq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detaches deferred data in this stream and it is back to active
|
* Detaches deferred data in this stream and it is back to active
|
||||||
|
|
|
@ -2201,7 +2201,9 @@ void test_nghttp2_session_on_window_update_received(void)
|
||||||
CU_ASSERT(1 == user_data.frame_recv_cb_called);
|
CU_ASSERT(1 == user_data.frame_recv_cb_called);
|
||||||
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE+16*1024 == stream->remote_window_size);
|
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE+16*1024 == stream->remote_window_size);
|
||||||
|
|
||||||
nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
CU_ASSERT(0 == nghttp2_stream_defer_data
|
||||||
|
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
|
||||||
|
&session->ob_pq));
|
||||||
|
|
||||||
CU_ASSERT(0 == nghttp2_session_on_window_update_received(session, &frame));
|
CU_ASSERT(0 == nghttp2_session_on_window_update_received(session, &frame));
|
||||||
CU_ASSERT(2 == user_data.frame_recv_cb_called);
|
CU_ASSERT(2 == user_data.frame_recv_cb_called);
|
||||||
|
|
Loading…
Reference in New Issue