Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1125 // We sent the frame successfully. | 1125 // We sent the frame successfully. |
| 1126 OnWriteComplete(rv); | 1126 OnWriteComplete(rv); |
| 1127 | 1127 |
| 1128 // TODO(mbelshe): Test this error case. Maybe we should mark the socket | 1128 // TODO(mbelshe): Test this error case. Maybe we should mark the socket |
| 1129 // as in an error state. | 1129 // as in an error state. |
| 1130 if (rv < 0) | 1130 if (rv < 0) |
| 1131 break; | 1131 break; |
| 1132 } | 1132 } |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 void SpdySession::CloseAllStreams(net::Error status) { | 1135 void SpdySession::CloseAllStreamsAfter(SpdyStreamId last_good_stream_id, |
| 1136 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); | 1136 net::Error status) { |
| 1137 base::StatsCounter abandoned_push_streams( | |
| 1138 "spdy.abandoned_push_streams"); | |
| 1139 | |
| 1140 if (!active_streams_.empty()) | |
| 1141 abandoned_streams.Add(active_streams_.size()); | |
| 1142 if (!unclaimed_pushed_streams_.empty()) { | |
| 1143 streams_abandoned_count_ += unclaimed_pushed_streams_.size(); | |
| 1144 abandoned_push_streams.Add(unclaimed_pushed_streams_.size()); | |
| 1145 unclaimed_pushed_streams_.clear(); | |
| 1146 } | |
| 1147 | |
| 1148 for (int i = 0; i < NUM_PRIORITIES; ++i) { | 1137 for (int i = 0; i < NUM_PRIORITIES; ++i) { |
| 1149 PendingStreamRequestQueue queue; | 1138 PendingStreamRequestQueue queue; |
| 1150 queue.swap(pending_create_stream_queues_[i]); | 1139 queue.swap(pending_create_stream_queues_[i]); |
| 1151 for (PendingStreamRequestQueue::const_iterator it = queue.begin(); | 1140 for (PendingStreamRequestQueue::const_iterator it = queue.begin(); |
| 1152 it != queue.end(); ++it) { | 1141 it != queue.end(); ++it) { |
| 1153 (*it)->OnRequestComplete(NULL, ERR_ABORTED); | 1142 (*it)->OnRequestComplete(NULL, ERR_ABORTED); |
| 1154 } | 1143 } |
| 1155 } | 1144 } |
| 1156 | 1145 |
| 1146 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.
| |
| 1157 while (!active_streams_.empty()) { | 1147 while (!active_streams_.empty()) { |
| 1158 ActiveStreamMap::iterator it = active_streams_.begin(); | 1148 ActiveStreamMap::iterator it = active_streams_.begin(); |
| 1159 const scoped_refptr<SpdyStream>& stream = it->second; | 1149 const scoped_refptr<SpdyStream>& stream = it->second; |
| 1150 if (stream->stream_id() <= last_good_stream_id) { | |
| 1151 new_active_streams[stream->stream_id()] = stream; | |
| 1152 active_streams_.erase(stream->stream_id()); | |
| 1153 continue; | |
| 1154 } | |
| 1160 LogAbandonedStream(stream, status); | 1155 LogAbandonedStream(stream, status); |
| 1161 DeleteStream(stream->stream_id(), status); | 1156 DeleteStream(stream->stream_id(), status); |
| 1157 streams_abandoned_count_++; | |
| 1162 } | 1158 } |
| 1159 active_streams_.swap(new_active_streams); | |
| 1160 DCHECK(new_active_streams.empty()); | |
| 1163 | 1161 |
| 1164 while (!created_streams_.empty()) { | 1162 while (!created_streams_.empty()) { |
| 1165 CreatedStreamSet::iterator it = created_streams_.begin(); | 1163 CreatedStreamSet::iterator it = created_streams_.begin(); |
| 1166 const scoped_refptr<SpdyStream> stream = *it; | 1164 const scoped_refptr<SpdyStream> stream = *it; |
| 1167 created_streams_.erase(it); | 1165 created_streams_.erase(it); |
| 1168 LogAbandonedStream(stream, status); | 1166 LogAbandonedStream(stream, status); |
| 1169 stream->OnClose(status); | 1167 stream->OnClose(status); |
| 1170 } | 1168 } |
| 1171 | 1169 |
| 1172 write_queue_.Clear(); | 1170 write_queue_.ClearAfter(last_good_stream_id); |
| 1171 } | |
| 1172 | |
| 1173 void SpdySession::CloseAllStreams(net::Error status) { | |
| 1174 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); | |
| 1175 base::StatsCounter abandoned_push_streams( | |
| 1176 "spdy.abandoned_push_streams"); | |
| 1177 | |
| 1178 if (!unclaimed_pushed_streams_.empty()) { | |
| 1179 streams_abandoned_count_ += unclaimed_pushed_streams_.size(); | |
| 1180 abandoned_push_streams.Add(unclaimed_pushed_streams_.size()); | |
| 1181 unclaimed_pushed_streams_.clear(); | |
| 1182 } | |
| 1183 | |
| 1184 CloseAllStreamsAfter(0, status); | |
| 1173 } | 1185 } |
| 1174 | 1186 |
| 1175 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, | 1187 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, |
| 1176 net::Error status) { | 1188 net::Error status) { |
| 1177 DCHECK(stream); | 1189 DCHECK(stream); |
| 1178 std::string description = base::StringPrintf( | 1190 std::string description = base::StringPrintf( |
| 1179 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); | 1191 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); |
| 1180 stream->LogStreamError(status, description); | 1192 stream->LogStreamError(status, description); |
| 1181 } | 1193 } |
| 1182 | 1194 |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1736 | 1748 |
| 1737 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, | 1749 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, |
| 1738 SpdyGoAwayStatus status) { | 1750 SpdyGoAwayStatus status) { |
| 1739 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY, | 1751 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY, |
| 1740 base::Bind(&NetLogSpdyGoAwayCallback, | 1752 base::Bind(&NetLogSpdyGoAwayCallback, |
| 1741 last_accepted_stream_id, | 1753 last_accepted_stream_id, |
| 1742 active_streams_.size(), | 1754 active_streams_.size(), |
| 1743 unclaimed_pushed_streams_.size(), | 1755 unclaimed_pushed_streams_.size(), |
| 1744 status)); | 1756 status)); |
| 1745 RemoveFromPool(); | 1757 RemoveFromPool(); |
| 1746 CloseAllStreams(net::ERR_ABORTED); | 1758 CloseAllStreamsAfter(last_accepted_stream_id, net::ERR_ABORTED); |
| 1747 | |
| 1748 // TODO(willchan): Cancel any streams that are past the GoAway frame's | |
| 1749 // |last_accepted_stream_id|. | |
| 1750 | |
| 1751 // Don't bother killing any streams that are still reading. They'll either | |
| 1752 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is | |
| 1753 // closed. | |
| 1754 } | 1759 } |
| 1755 | 1760 |
| 1756 void SpdySession::OnPing(uint32 unique_id) { | 1761 void SpdySession::OnPing(uint32 unique_id) { |
| 1757 net_log_.AddEvent( | 1762 net_log_.AddEvent( |
| 1758 NetLog::TYPE_SPDY_SESSION_PING, | 1763 NetLog::TYPE_SPDY_SESSION_PING, |
| 1759 base::Bind(&NetLogSpdyPingCallback, unique_id, "received")); | 1764 base::Bind(&NetLogSpdyPingCallback, unique_id, "received")); |
| 1760 | 1765 |
| 1761 // Send response to a PING from server. | 1766 // Send response to a PING from server. |
| 1762 if (unique_id % 2 == 0) { | 1767 if (unique_id % 2 == 0) { |
| 1763 WritePingFrame(unique_id); | 1768 WritePingFrame(unique_id); |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2333 } | 2338 } |
| 2334 | 2339 |
| 2335 session_recv_window_size_ -= delta_window_size; | 2340 session_recv_window_size_ -= delta_window_size; |
| 2336 net_log_.AddEvent( | 2341 net_log_.AddEvent( |
| 2337 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2342 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
| 2338 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2343 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2339 -delta_window_size, session_recv_window_size_)); | 2344 -delta_window_size, session_recv_window_size_)); |
| 2340 } | 2345 } |
| 2341 | 2346 |
| 2342 } // namespace net | 2347 } // namespace net |
| OLD | NEW |