From 6f30decf79da066bb199163a820a31fb057c0157 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 22 Jul 2015 23:11:56 -0700
Subject: [PATCH] Flow control fix

---
 src/core/transport/chttp2/writing.c |  3 ++-
 test/cpp/end2end/end2end_test.cc    | 20 ++++++++++++++++++++
 test/cpp/util/messages.proto        |  1 +
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index d8ec117aa5..041c4efd1f 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -66,7 +66,8 @@ int grpc_chttp2_unlocking_check_writes(
   /* for each grpc_chttp2_stream that's become writable, frame it's data
      (according to
      available window sizes) and add to the output buffer */
-  while (grpc_chttp2_list_pop_writable_stream(transport_global,
+  while (transport_global->outgoing_window > 0 &&
+         grpc_chttp2_list_pop_writable_stream(transport_global,
                                               transport_writing, &stream_global,
                                               &stream_writing)) {
     stream_writing->id = stream_global->id;
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 20e4c4ed55..c433b78948 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -144,6 +144,11 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
     if (request->has_param() && request->param().check_auth_context()) {
       CheckAuthContext(context);
     }
+    if (request->has_param() &&
+        request->param().response_message_length() > 0) {
+      response->set_message(
+          grpc::string(request->param().response_message_length(), '\0'));
+    }
     return Status::OK;
   }
 
@@ -786,6 +791,21 @@ TEST_F(End2endTest, ClientAuthContext) {
   CheckAuthContext(&context);
 }
 
+// Make the response larger than the flow control window.
+TEST_F(End2endTest, HugeResponse) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  request.set_message("huge response");
+  const int kResponseSize = 1024 * (1024 + 10);
+  request.mutable_param()->set_response_message_length(kResponseSize);
+
+  ClientContext context;
+  Status s = stub_->Echo(&context, request, &response);
+  EXPECT_EQ(kResponseSize, response.message().size());
+  EXPECT_TRUE(s.ok());
+}
+
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
index 3708972b90..2fad8b42a2 100644
--- a/test/cpp/util/messages.proto
+++ b/test/cpp/util/messages.proto
@@ -38,6 +38,7 @@ message RequestParams {
   optional int32 server_cancel_after_us = 3;
   optional bool echo_metadata = 4;
   optional bool check_auth_context = 5;
+  optional int32 response_message_length = 6;
 }
 
 message EchoRequest {
-- 
GitLab