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