Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 14232014: Correctly handle SPDY GOAWAY frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698