Index: net/spdy/spdy_session.cc |
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc |
index ba84ea12acbbe9e41dfea287860e52eda6fdbbef..44ca9d4c3268a5ed8bc334c8b6d144a3e975b02e 100644 |
--- a/net/spdy/spdy_session.cc |
+++ b/net/spdy/spdy_session.cc |
@@ -1132,19 +1132,8 @@ void SpdySession::WriteSocket() { |
} |
} |
-void SpdySession::CloseAllStreams(net::Error status) { |
- base::StatsCounter abandoned_streams("spdy.abandoned_streams"); |
- base::StatsCounter abandoned_push_streams( |
- "spdy.abandoned_push_streams"); |
- |
- if (!active_streams_.empty()) |
- abandoned_streams.Add(active_streams_.size()); |
- if (!unclaimed_pushed_streams_.empty()) { |
- streams_abandoned_count_ += unclaimed_pushed_streams_.size(); |
- abandoned_push_streams.Add(unclaimed_pushed_streams_.size()); |
- unclaimed_pushed_streams_.clear(); |
- } |
- |
+void SpdySession::CloseAllStreamsAfter(SpdyStreamId last_good_stream_id, |
+ net::Error status) { |
for (int i = 0; i < NUM_PRIORITIES; ++i) { |
PendingStreamRequestQueue queue; |
queue.swap(pending_create_stream_queues_[i]); |
@@ -1154,12 +1143,21 @@ void SpdySession::CloseAllStreams(net::Error status) { |
} |
} |
+ ActiveStreamMap new_active_streams; |
akalin
2013/04/17 21:14:20
Curious -- are we worried about re-entrancy here?
Ryan Hamilton
2013/04/18 00:30:40
Done.
|
while (!active_streams_.empty()) { |
ActiveStreamMap::iterator it = active_streams_.begin(); |
const scoped_refptr<SpdyStream>& stream = it->second; |
+ if (stream->stream_id() <= last_good_stream_id) { |
+ new_active_streams[stream->stream_id()] = stream; |
+ active_streams_.erase(stream->stream_id()); |
+ continue; |
+ } |
LogAbandonedStream(stream, status); |
DeleteStream(stream->stream_id(), status); |
+ streams_abandoned_count_++; |
} |
+ active_streams_.swap(new_active_streams); |
+ DCHECK(new_active_streams.empty()); |
while (!created_streams_.empty()) { |
CreatedStreamSet::iterator it = created_streams_.begin(); |
@@ -1169,7 +1167,21 @@ void SpdySession::CloseAllStreams(net::Error status) { |
stream->OnClose(status); |
} |
- write_queue_.Clear(); |
+ write_queue_.ClearAfter(last_good_stream_id); |
+} |
+ |
+void SpdySession::CloseAllStreams(net::Error status) { |
+ base::StatsCounter abandoned_streams("spdy.abandoned_streams"); |
+ base::StatsCounter abandoned_push_streams( |
+ "spdy.abandoned_push_streams"); |
+ |
+ if (!unclaimed_pushed_streams_.empty()) { |
+ streams_abandoned_count_ += unclaimed_pushed_streams_.size(); |
+ abandoned_push_streams.Add(unclaimed_pushed_streams_.size()); |
+ unclaimed_pushed_streams_.clear(); |
+ } |
+ |
+ CloseAllStreamsAfter(0, status); |
} |
void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, |
@@ -1743,14 +1755,7 @@ void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, |
unclaimed_pushed_streams_.size(), |
status)); |
RemoveFromPool(); |
- CloseAllStreams(net::ERR_ABORTED); |
- |
- // TODO(willchan): Cancel any streams that are past the GoAway frame's |
- // |last_accepted_stream_id|. |
- |
- // Don't bother killing any streams that are still reading. They'll either |
- // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is |
- // closed. |
+ CloseAllStreamsAfter(last_accepted_stream_id, net::ERR_ABORTED); |
} |
void SpdySession::OnPing(uint32 unique_id) { |