From 49119a4caf48c20ed3655e0e5637129c9ed94481 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 8 Sep 2017 15:29:19 -0700 Subject: [PATCH] Fix for max_concurrent_streams issue - Call mark_stream_closed before sending trailing metadata --- .../ext/transport/chttp2/transport/chttp2_transport.c | 8 +++++++- .../ext/transport/chttp2/transport/frame_rst_stream.c | 3 +++ src/core/ext/transport/chttp2/transport/hpack_parser.c | 1 + src/core/ext/transport/chttp2/transport/writing.c | 8 ++++---- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 3fd701fe2f1..5fb943d3ca8 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1974,6 +1974,10 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) { s->seen_error = true; } + if (!s->write_closed) { + grpc_chttp2_fail_pending_writes(exec_ctx, t, s, + GRPC_ERROR_REF(due_to_error)); + } grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error); } @@ -2103,7 +2107,6 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, if (close_writes && !s->write_closed) { s->write_closed_error = GRPC_ERROR_REF(error); s->write_closed = true; - grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); } if (s->read_closed && s->write_closed) { became_closed = true; @@ -2288,6 +2291,9 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR, &s->stats.outgoing)); + if (!s->write_closed) { + grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); + } grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error); grpc_chttp2_initiate_write(exec_ctx, t, "close_from_api"); } diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c index 0133b6efa25..d77097811a9 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -103,6 +103,9 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx, GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason); gpr_free(message); } + if (!s->write_closed) { + grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); + } grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, error); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 82ff2c8e2cf..e4f2ae84759 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1650,6 +1650,7 @@ static void force_client_rst_stream(grpc_exec_ctx *exec_ctx, void *sp, &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR, &s->stats.outgoing)); grpc_chttp2_initiate_write(exec_ctx, t, "force_rst_stream"); + grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_NONE); grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, GRPC_ERROR_NONE); } GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "final_rst"); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index fa224a49a45..7512fe122d5 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -386,6 +386,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( if (is_last_frame) { s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, + GRPC_ERROR_NONE); if (!t->is_client && !s->read_closed) { grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_rst_stream_create( s->id, GRPC_HTTP2_NO_ERROR, @@ -444,6 +446,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( } s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, + GRPC_ERROR_NONE); if (!t->is_client && !s->read_closed) { grpc_slice_buffer_add( &t->outbuf, grpc_chttp2_rst_stream_create( @@ -519,10 +523,6 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_ERROR_REF(error)); s->sending_bytes = 0; } - if (s->sent_trailing_metadata) { - grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, - GRPC_ERROR_REF(error)); - } GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end"); } grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->outbuf);