| Index: net/quic/core/quic_session.cc
|
| diff --git a/net/quic/core/quic_session.cc b/net/quic/core/quic_session.cc
|
| index 3afc985adf101ab9bbfab38163fd287a2c6921b8..7c1bf263417842c0957aeb5482dd6e935d23f0eb 100644
|
| --- a/net/quic/core/quic_session.cc
|
| +++ b/net/quic/core/quic_session.cc
|
| @@ -45,10 +45,15 @@ QuicSession::QuicSession(QuicConnection* connection,
|
| perspective() == Perspective::IS_SERVER,
|
| nullptr),
|
| currently_writing_stream_id_(0),
|
| - respect_goaway_(true) {}
|
| + respect_goaway_(true),
|
| + use_stream_notifier_(
|
| + FLAGS_quic_reloadable_flag_quic_use_stream_notifier) {}
|
|
|
| void QuicSession::Initialize() {
|
| connection_->set_visitor(this);
|
| + if (use_stream_notifier_) {
|
| + connection_->SetStreamNotifier(this);
|
| + }
|
| connection_->SetFromConfig(config_);
|
|
|
| DCHECK_EQ(kCryptoStreamId, GetMutableCryptoStream()->id());
|
| @@ -66,6 +71,7 @@ QuicSession::~QuicSession() {
|
| << "Surprisingly high number of locally closed self initiated streams"
|
| "still waiting for final byte offset: "
|
| << GetNumLocallyClosedOutgoingStreamsHighestOffset();
|
| + QUIC_LOG_IF(WARNING, !zombie_streams_.empty()) << "Still have zombie streams";
|
| }
|
|
|
| void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
|
| @@ -129,6 +135,13 @@ void QuicSession::OnConnectionClosed(QuicErrorCode error,
|
| }
|
| }
|
|
|
| + // Cleanup zombie stream map on connection close.
|
| + while (!zombie_streams_.empty()) {
|
| + ZombieStreamMap::iterator it = zombie_streams_.begin();
|
| + closed_streams_.push_back(std::move(it->second));
|
| + zombie_streams_.erase(it);
|
| + }
|
| +
|
| if (visitor_) {
|
| visitor_->OnConnectionClosed(connection_->connection_id(), error,
|
| error_details);
|
| @@ -369,7 +382,11 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) {
|
| stream->set_rst_sent(true);
|
| }
|
|
|
| - closed_streams_.push_back(std::move(it->second));
|
| + if (stream->IsWaitingForAcks()) {
|
| + zombie_streams_[stream->id()] = std::move(it->second);
|
| + } else {
|
| + closed_streams_.push_back(std::move(it->second));
|
| + }
|
|
|
| // If we haven't received a FIN or RST for this stream, we need to keep track
|
| // of the how many bytes the stream's flow controller believes it has
|
| @@ -944,4 +961,45 @@ QuicStream* QuicSession::CreateAndActivateStream(QuicStreamId id) {
|
| return stream_ptr;
|
| }
|
|
|
| +void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) {
|
| + auto it = zombie_streams_.find(id);
|
| + if (it == zombie_streams_.end()) {
|
| + return;
|
| + }
|
| +
|
| + closed_streams_.push_back(std::move(it->second));
|
| + zombie_streams_.erase(it);
|
| +}
|
| +
|
| +QuicStream* QuicSession::GetStream(QuicStreamId id) const {
|
| + auto static_stream = static_stream_map_.find(id);
|
| + if (static_stream != static_stream_map_.end()) {
|
| + return static_stream->second;
|
| + }
|
| + auto active_stream = dynamic_stream_map_.find(id);
|
| + if (active_stream != dynamic_stream_map_.end()) {
|
| + return active_stream->second.get();
|
| + }
|
| + auto zombie_stream = zombie_streams_.find(id);
|
| + if (zombie_stream != zombie_streams_.end()) {
|
| + return zombie_stream->second.get();
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +void QuicSession::OnStreamFrameAcked(const QuicStreamFrame& frame,
|
| + QuicTime::Delta ack_delay_time) {
|
| + QuicStream* stream = GetStream(frame.stream_id);
|
| + if (stream != nullptr) {
|
| + stream->OnStreamFrameAcked(frame, ack_delay_time);
|
| + }
|
| +}
|
| +
|
| +void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
|
| + QuicStream* stream = GetStream(frame.stream_id);
|
| + if (stream != nullptr) {
|
| + stream->OnStreamFrameRetransmitted(frame);
|
| + }
|
| +}
|
| +
|
| } // namespace net
|
|
|