Ensure QuicTransportStream::Visitor::OnFinRead() is only called once.
This fixes a non-deterministic crash in Chromium tests: https://bugs.chromium.org/p/chromium/issues/detail?id=1065854. This also fixes a potential bug in which the stream is never marked as closed.
gfe-relnote: n/a (code not used in production)
PiperOrigin-RevId: 303787933
Change-Id: I3c4f39e709e27dc5f81ccc78729323da1810fda5
diff --git a/quic/quic_transport/quic_transport_stream.cc b/quic/quic_transport/quic_transport_stream.cc
index 2824771..401ae7e 100644
--- a/quic/quic_transport/quic_transport_stream.cc
+++ b/quic/quic_transport/quic_transport_stream.cc
@@ -35,8 +35,8 @@
iov.iov_base = buffer;
iov.iov_len = buffer_size;
const size_t result = sequencer()->Readv(&iov, 1);
- if (sequencer()->IsClosed() && visitor_ != nullptr) {
- visitor_->OnFinRead();
+ if (sequencer()->IsClosed()) {
+ MaybeNotifyFinRead();
}
return result;
}
@@ -111,10 +111,7 @@
void QuicTransportStream::OnDataAvailable() {
if (sequencer()->IsClosed()) {
- if (visitor_ != nullptr) {
- visitor_->OnFinRead();
- }
- OnFinRead();
+ MaybeNotifyFinRead();
return;
}
@@ -138,4 +135,13 @@
}
}
+void QuicTransportStream::MaybeNotifyFinRead() {
+ if (visitor_ == nullptr || fin_read_notified_) {
+ return;
+ }
+ fin_read_notified_ = true;
+ visitor_->OnFinRead();
+ OnFinRead();
+}
+
} // namespace quic
diff --git a/quic/quic_transport/quic_transport_stream.h b/quic/quic_transport/quic_transport_stream.h
index d558cdb..f2bac88 100644
--- a/quic/quic_transport/quic_transport_stream.h
+++ b/quic/quic_transport/quic_transport_stream.h
@@ -63,8 +63,11 @@
using QuicStream::WriteMemSlices;
using QuicStream::WriteOrBufferData;
+ void MaybeNotifyFinRead();
+
QuicTransportSessionInterface* session_interface_;
std::unique_ptr<Visitor> visitor_ = nullptr;
+ bool fin_read_notified_ = false;
};
} // namespace quic