In quic, add num_draining_outgoing_streams_ to quicsession, and this counter will be used to determine shouldkeepconnectionalive in quicspdyclientsessionbase. client side only. not protected.

PiperOrigin-RevId: 314396250
Change-Id: I4873bdcdac03fd2d07d4caf5f7ce9d702e3b045f
diff --git a/quic/core/http/quic_spdy_client_session_base.cc b/quic/core/http/quic_spdy_client_session_base.cc
index 21ecfee..04f8594 100644
--- a/quic/core/http/quic_spdy_client_session_base.cc
+++ b/quic/core/http/quic_spdy_client_session_base.cc
@@ -228,6 +228,11 @@
   return !HasActiveRequestStreams() && promised_by_id_.empty();
 }
 
+bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
+  return QuicSpdySession::ShouldKeepConnectionAlive() ||
+         num_outgoing_draining_streams() > 0;
+}
+
 void QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
   QuicSpdySession::OnSettingsFrame(frame);
   std::unique_ptr<char[]> buffer;
diff --git a/quic/core/http/quic_spdy_client_session_base.h b/quic/core/http/quic_spdy_client_session_base.h
index a3c9aac..20f4087 100644
--- a/quic/core/http/quic_spdy_client_session_base.h
+++ b/quic/core/http/quic_spdy_client_session_base.h
@@ -110,6 +110,9 @@
   // Returns true if there are no active requests and no promised streams.
   bool ShouldReleaseHeadersStreamSequencerBuffer() override;
 
+  // Override to wait for all received responses to be consumed by application.
+  bool ShouldKeepConnectionAlive() const override;
+
   size_t get_max_promises() const {
     return max_open_incoming_unidirectional_streams() *
            kMaxPromisedStreamsMultiplier;
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index cdb8b31..1eb69e9 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -74,6 +74,7 @@
                             config_.GetMaxUnidirectionalStreamsToSend() +
                                 num_expected_unidirectional_static_streams),
       num_draining_streams_(0),
+      num_outgoing_draining_streams_(0),
       num_static_streams_(0),
       flow_controller_(
           this,
@@ -905,6 +906,10 @@
   if (stream_was_draining) {
     QUIC_BUG_IF(num_draining_streams_ == 0);
     --num_draining_streams_;
+    if (!IsIncomingStream(stream_id)) {
+      QUIC_BUG_IF(num_outgoing_draining_streams_ == 0);
+      --num_outgoing_draining_streams_;
+    }
     // Stream Id manager has been informed with draining streams.
     return;
   }
@@ -1664,6 +1669,7 @@
   }
   ++num_draining_streams_;
   if (!IsIncomingStream(stream_id)) {
+    ++num_outgoing_draining_streams_;
     OnCanCreateNewOutgoingStream(unidirectional);
   }
 }
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index 32aad51..c9e3216 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -594,6 +594,10 @@
 
   size_t num_static_streams() const { return num_static_streams_; }
 
+  size_t num_outgoing_draining_streams() const {
+    return num_outgoing_draining_streams_;
+  }
+
   // Processes the stream type information of |pending| depending on
   // different kinds of sessions' own rules. Returns true if the pending stream
   // is converted into a normal stream.
@@ -738,6 +742,10 @@
   // application to consume data.
   size_t num_draining_streams_;
 
+  // A counter for self initiated streams which have sent and received FIN but
+  // waiting for application to consume data.
+  size_t num_outgoing_draining_streams_;
+
   // A counter for static streams which are in stream_map_.
   size_t num_static_streams_;