gfe-relnote: In QUIC, break QuicStream::CloseRWSide -> QuicSession::CloseStream -> QuicStream::OnClose -> CloseRWSide loop. Protected by gfe2_reloadable_flag_quic_break_session_stream_close_loop.

With this change, a stream can be closed by 4 methods:
1) QuicSession::CloseStream (will soon be removed)
2) QuicSession::ResetStream
3) QuicStream::Reset
4) QuicStream::OnStreamReset
And also make the code path consistent. All -> QuicStream::CloseReadSide/CloseWriteSide -> QuicSession::OnStreamClosed.

PiperOrigin-RevId: 307032801
Change-Id: I1a2f49ddb94cc9642ce8c8fcb514f5adb928d045
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
index 813ea2d..75cb9f9 100644
--- a/quic/core/quic_stream.cc
+++ b/quic/core/quic_stream.cc
@@ -573,9 +573,16 @@
 
 void QuicStream::Reset(QuicRstStreamErrorCode error) {
   stream_error_ = error;
-  // Sending a RstStream results in calling CloseStream.
   session()->SendRstStream(id(), error, stream_bytes_written());
   rst_sent_ = true;
+  if (session_->break_close_loop()) {
+    if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+      session()->OnStreamDoneWaitingForAcks(id_);
+      return;
+    }
+    CloseReadSide();
+    CloseWriteSide();
+  }
 }
 
 void QuicStream::OnUnrecoverableError(QuicErrorCode error,
@@ -762,7 +769,12 @@
 
   if (write_side_closed_) {
     QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
-    session_->CloseStream(id());
+    if (session_->break_close_loop()) {
+      session_->OnStreamClosed(id());
+      OnClose();
+    } else {
+      session_->CloseStream(id());
+    }
   }
 }
 
@@ -775,7 +787,12 @@
   write_side_closed_ = true;
   if (read_side_closed_) {
     QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
-    session_->CloseStream(id());
+    if (session_->break_close_loop()) {
+      session_->OnStreamClosed(id());
+      OnClose();
+    } else {
+      session_->CloseStream(id());
+    }
   }
 }
 
@@ -798,8 +815,12 @@
 }
 
 void QuicStream::OnClose() {
-  CloseReadSide();
-  CloseWriteSide();
+  if (session()->break_close_loop()) {
+    DCHECK(read_side_closed_ && write_side_closed_);
+  } else {
+    CloseReadSide();
+    CloseWriteSide();
+  }
 
   if (!fin_sent_ && !rst_sent_) {
     // For flow control accounting, tell the peer how many bytes have been