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

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

Issue 8230037: Send PING to check the status of the SPDY connection. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/auto_reset.h"
7 #include "base/basictypes.h" 8 #include "base/basictypes.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/memory/linked_ptr.h" 10 #include "base/memory/linked_ptr.h"
10 #include "base/message_loop.h" 11 #include "base/message_loop.h"
11 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
12 #include "base/metrics/stats_counters.h" 13 #include "base/metrics/stats_counters.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
15 #include "base/string_util.h" 16 #include "base/string_util.h"
16 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 166 }
166 167
167 private: 168 private:
168 ~NetLogSpdyRstParameter() {} 169 ~NetLogSpdyRstParameter() {}
169 const spdy::SpdyStreamId stream_id_; 170 const spdy::SpdyStreamId stream_id_;
170 const int status_; 171 const int status_;
171 172
172 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyRstParameter); 173 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyRstParameter);
173 }; 174 };
174 175
176 class NetLogSpdyPingParameter : public NetLog::EventParameters {
177 public:
178 explicit NetLogSpdyPingParameter(uint32 unique_id) : unique_id_(unique_id) {}
179
180 virtual Value* ToValue() const {
181 DictionaryValue* dict = new DictionaryValue();
182 dict->SetInteger("unique_id", unique_id_);
183 return dict;
184 }
185
186 private:
187 ~NetLogSpdyPingParameter() {}
jar (doing other things) 2011/10/14 19:59:07 Question for WillChan: Does making this private pr
willchan no longer on Chromium 2011/10/14 22:49:21 Refcounted
ramant (doing other things) 2011/10/14 23:42:45 Done.
ramant (doing other things) 2011/10/14 23:42:45 Done.
188 const uint32 unique_id_;
189
190 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyPingParameter);
191 };
192
175 class NetLogSpdyGoAwayParameter : public NetLog::EventParameters { 193 class NetLogSpdyGoAwayParameter : public NetLog::EventParameters {
176 public: 194 public:
177 NetLogSpdyGoAwayParameter(spdy::SpdyStreamId last_stream_id, 195 NetLogSpdyGoAwayParameter(spdy::SpdyStreamId last_stream_id,
178 int active_streams, 196 int active_streams,
179 int unclaimed_streams) 197 int unclaimed_streams)
180 : last_stream_id_(last_stream_id), 198 : last_stream_id_(last_stream_id),
181 active_streams_(active_streams), 199 active_streams_(active_streams),
182 unclaimed_streams_(unclaimed_streams) {} 200 unclaimed_streams_(unclaimed_streams) {}
183 201
184 virtual Value* ToValue() const { 202 virtual Value* ToValue() const {
(...skipping 21 matching lines...) Expand all
206 224
207 // static 225 // static
208 bool SpdySession::use_flow_control_ = false; 226 bool SpdySession::use_flow_control_ = false;
209 227
210 // static 228 // static
211 size_t SpdySession::init_max_concurrent_streams_ = 10; 229 size_t SpdySession::init_max_concurrent_streams_ = 10;
212 230
213 // static 231 // static
214 size_t SpdySession::max_concurrent_stream_limit_ = 256; 232 size_t SpdySession::max_concurrent_stream_limit_ = 256;
215 233
234 // static
235 bool SpdySession::send_ping_for_every_request_ = false;
236
237 // static
238 int SpdySession::post_ping_delay_time_ms_ = 1000;
239
240 // static
241 int SpdySession::check_status_delay_time_ms_ = 10000;
242
243 // static
244 int SpdySession::hung_interval_ms_ = 10000;
245
216 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, 246 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
217 SpdySessionPool* spdy_session_pool, 247 SpdySessionPool* spdy_session_pool,
218 SpdySettingsStorage* spdy_settings, 248 SpdySettingsStorage* spdy_settings,
219 bool verify_domain_authentication, 249 bool verify_domain_authentication,
220 NetLog* net_log) 250 NetLog* net_log)
221 : ALLOW_THIS_IN_INITIALIZER_LIST( 251 : ALLOW_THIS_IN_INITIALIZER_LIST(
222 read_callback_(this, &SpdySession::OnReadComplete)), 252 read_callback_(this, &SpdySession::OnReadComplete)),
223 ALLOW_THIS_IN_INITIALIZER_LIST( 253 ALLOW_THIS_IN_INITIALIZER_LIST(
224 write_callback_(this, &SpdySession::OnWriteComplete)), 254 write_callback_(this, &SpdySession::OnWriteComplete)),
225 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), 255 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
(...skipping 13 matching lines...) Expand all
239 max_concurrent_streams_(init_max_concurrent_streams_), 269 max_concurrent_streams_(init_max_concurrent_streams_),
240 streams_initiated_count_(0), 270 streams_initiated_count_(0),
241 streams_pushed_count_(0), 271 streams_pushed_count_(0),
242 streams_pushed_and_claimed_count_(0), 272 streams_pushed_and_claimed_count_(0),
243 streams_abandoned_count_(0), 273 streams_abandoned_count_(0),
244 frames_received_(0), 274 frames_received_(0),
245 bytes_received_(0), 275 bytes_received_(0),
246 sent_settings_(false), 276 sent_settings_(false),
247 received_settings_(false), 277 received_settings_(false),
248 stalled_streams_(0), 278 stalled_streams_(0),
279 pings_in_flight_(0),
280 unique_id_counter_(1),
281 post_ping_pending_(false),
282 check_status_pending_(false),
283 last_sent_was_ping_(false),
249 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), 284 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize),
250 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), 285 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize),
251 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), 286 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
252 verify_domain_authentication_(verify_domain_authentication) { 287 verify_domain_authentication_(verify_domain_authentication) {
jar (doing other things) 2011/10/14 19:59:07 Since we just got data over the underlying TCP/IP
ramant (doing other things) 2011/10/14 23:42:45 Done.
253 DCHECK(HttpStreamFactory::spdy_enabled()); 288 DCHECK(HttpStreamFactory::spdy_enabled());
254 net_log_.BeginEvent( 289 net_log_.BeginEvent(
255 NetLog::TYPE_SPDY_SESSION, 290 NetLog::TYPE_SPDY_SESSION,
256 make_scoped_refptr( 291 make_scoped_refptr(
257 new NetLogSpdySessionParameter(host_port_proxy_pair_))); 292 new NetLogSpdySessionParameter(host_port_proxy_pair_)));
258 293
259 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. 294 // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
260 295
261 spdy_framer_.set_visitor(this); 296 spdy_framer_.set_visitor(this);
262 297
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 spdy::SpdyStreamId stream_id, 502 spdy::SpdyStreamId stream_id,
468 RequestPriority priority, 503 RequestPriority priority,
469 spdy::SpdyControlFlags flags, 504 spdy::SpdyControlFlags flags,
470 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { 505 const linked_ptr<spdy::SpdyHeaderBlock>& headers) {
471 // Find our stream 506 // Find our stream
472 if (!IsStreamActive(stream_id)) 507 if (!IsStreamActive(stream_id))
473 return ERR_INVALID_SPDY_STREAM; 508 return ERR_INVALID_SPDY_STREAM;
474 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; 509 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
475 CHECK_EQ(stream->stream_id(), stream_id); 510 CHECK_EQ(stream->stream_id(), stream_id);
476 511
512 SendPing();
jar (doing other things) 2011/10/14 19:59:07 We need a better name, since this confused me into
ramant (doing other things) 2011/10/14 23:42:45 Done.
513
477 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame( 514 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame(
478 spdy_framer_.CreateSynStream( 515 spdy_framer_.CreateSynStream(
479 stream_id, 0, 516 stream_id, 0,
480 ConvertRequestPriorityToSpdyPriority(priority), 517 ConvertRequestPriorityToSpdyPriority(priority),
481 flags, false, headers.get())); 518 flags, false, headers.get()));
482 QueueFrame(syn_frame.get(), priority, stream); 519 QueueFrame(syn_frame.get(), priority, stream);
483 520
484 base::StatsCounter spdy_requests("spdy.requests"); 521 base::StatsCounter spdy_requests("spdy.requests");
485 spdy_requests.Increment(); 522 spdy_requests.Increment();
486 streams_initiated_count_++; 523 streams_initiated_count_++;
487 524
488 if (net_log().IsLoggingAllEvents()) { 525 if (net_log().IsLoggingAllEvents()) {
489 net_log().AddEvent( 526 net_log().AddEvent(
490 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 527 NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
491 make_scoped_refptr( 528 make_scoped_refptr(
492 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); 529 new NetLogSpdySynParameter(headers, flags, stream_id, 0)));
493 } 530 }
531 last_sent_was_ping_ = false;
494 532
495 return ERR_IO_PENDING; 533 return ERR_IO_PENDING;
496 } 534 }
497 535
498 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, 536 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id,
499 net::IOBuffer* data, int len, 537 net::IOBuffer* data, int len,
500 spdy::SpdyDataFlags flags) { 538 spdy::SpdyDataFlags flags) {
501 // Find our stream 539 // Find our stream
jar (doing other things) 2011/10/14 19:59:07 We should probably (just for safety and correctnes
ramant (doing other things) 2011/10/14 23:42:45 Done.
502 DCHECK(IsStreamActive(stream_id)); 540 DCHECK(IsStreamActive(stream_id));
503 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 541 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
504 CHECK_EQ(stream->stream_id(), stream_id); 542 CHECK_EQ(stream->stream_id(), stream_id);
505 if (!stream) 543 if (!stream)
506 return ERR_INVALID_SPDY_STREAM; 544 return ERR_INVALID_SPDY_STREAM;
507 545
508 if (len > kMaxSpdyFrameChunkSize) { 546 if (len > kMaxSpdyFrameChunkSize) {
509 len = kMaxSpdyFrameChunkSize; 547 len = kMaxSpdyFrameChunkSize;
510 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN); 548 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN);
511 } 549 }
(...skipping 25 matching lines...) Expand all
537 if (net_log().IsLoggingAllEvents()) { 575 if (net_log().IsLoggingAllEvents()) {
538 net_log().AddEvent( 576 net_log().AddEvent(
539 NetLog::TYPE_SPDY_SESSION_SEND_DATA, 577 NetLog::TYPE_SPDY_SESSION_SEND_DATA,
540 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); 578 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags)));
541 } 579 }
542 580
543 // TODO(mbelshe): reduce memory copies here. 581 // TODO(mbelshe): reduce memory copies here.
544 scoped_ptr<spdy::SpdyDataFrame> frame( 582 scoped_ptr<spdy::SpdyDataFrame> frame(
545 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); 583 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags));
546 QueueFrame(frame.get(), stream->priority(), stream); 584 QueueFrame(frame.get(), stream->priority(), stream);
585 last_sent_was_ping_ = false;
547 return ERR_IO_PENDING; 586 return ERR_IO_PENDING;
548 } 587 }
549 588
550 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { 589 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) {
551 // TODO(mbelshe): We should send a RST_STREAM control frame here 590 // TODO(mbelshe): We should send a RST_STREAM control frame here
552 // so that the server can cancel a large send. 591 // so that the server can cancel a large send.
553 592
554 DeleteStream(stream_id, status); 593 DeleteStream(stream_id, status);
555 } 594 }
556 595
557 void SpdySession::ResetStream( 596 void SpdySession::ResetStream(
558 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { 597 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) {
559 598
560 net_log().AddEvent( 599 net_log().AddEvent(
561 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, 600 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM,
562 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); 601 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status)));
563 602
564 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( 603 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame(
565 spdy_framer_.CreateRstStream(stream_id, status)); 604 spdy_framer_.CreateRstStream(stream_id, status));
566 605
567 // Default to lowest priority unless we know otherwise. 606 // Default to lowest priority unless we know otherwise.
568 int priority = 3; 607 int priority = 3;
569 if(IsStreamActive(stream_id)) { 608 if(IsStreamActive(stream_id)) {
570 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 609 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
571 priority = stream->priority(); 610 priority = stream->priority();
572 } 611 }
573 QueueFrame(rst_frame.get(), priority, NULL); 612 QueueFrame(rst_frame.get(), priority, NULL);
574 613 last_sent_was_ping_ = false;
575 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); 614 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
576 } 615 }
577 616
578 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { 617 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const {
579 return ContainsKey(active_streams_, stream_id); 618 return ContainsKey(active_streams_, stream_id);
580 } 619 }
581 620
582 LoadState SpdySession::GetLoadState() const { 621 LoadState SpdySession::GetLoadState() const {
583 // NOTE: The application only queries the LoadState via the 622 // NOTE: The application only queries the LoadState via the
584 // SpdyNetworkTransaction, and details are only needed when 623 // SpdyNetworkTransaction, and details are only needed when
(...skipping 20 matching lines...) Expand all
605 // Session is tearing down. 644 // Session is tearing down.
606 net::Error error = static_cast<net::Error>(bytes_read); 645 net::Error error = static_cast<net::Error>(bytes_read);
607 if (bytes_read == 0) 646 if (bytes_read == 0)
608 error = ERR_CONNECTION_CLOSED; 647 error = ERR_CONNECTION_CLOSED;
609 CloseSessionOnError(error, true); 648 CloseSessionOnError(error, true);
610 return; 649 return;
611 } 650 }
612 651
613 bytes_received_ += bytes_read; 652 bytes_received_ += bytes_read;
614 653
654 received_data_time_ = base::TimeTicks::Now();
655
615 // The SpdyFramer will use callbacks onto |this| as it parses frames. 656 // The SpdyFramer will use callbacks onto |this| as it parses frames.
616 // When errors occur, those callbacks can lead to teardown of all references 657 // When errors occur, those callbacks can lead to teardown of all references
617 // to |this|, so maintain a reference to self during this call for safe 658 // to |this|, so maintain a reference to self during this call for safe
618 // cleanup. 659 // cleanup.
619 scoped_refptr<SpdySession> self(this); 660 scoped_refptr<SpdySession> self(this);
620 661
621 char *data = read_buffer_->data(); 662 char *data = read_buffer_->data();
622 while (bytes_read && 663 while (bytes_read &&
623 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) { 664 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) {
624 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read); 665 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read);
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1222 return; 1263 return;
1223 } 1264 }
1224 } 1265 }
1225 1266
1226 frames_received_++; 1267 frames_received_++;
1227 1268
1228 switch (type) { 1269 switch (type) {
1229 case spdy::GOAWAY: 1270 case spdy::GOAWAY:
1230 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); 1271 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame));
1231 break; 1272 break;
1273 case spdy::PING:
1274 OnPing(*reinterpret_cast<const spdy::SpdyPingControlFrame*>(frame));
1275 break;
1232 case spdy::SETTINGS: 1276 case spdy::SETTINGS:
1233 OnSettings( 1277 OnSettings(
1234 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); 1278 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame));
1235 break; 1279 break;
1236 case spdy::RST_STREAM: 1280 case spdy::RST_STREAM:
1237 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); 1281 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame));
1238 break; 1282 break;
1239 case spdy::SYN_STREAM: 1283 case spdy::SYN_STREAM:
1240 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), 1284 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame),
1241 headers); 1285 headers);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 CloseAllStreams(net::ERR_ABORTED); 1354 CloseAllStreams(net::ERR_ABORTED);
1311 1355
1312 // TODO(willchan): Cancel any streams that are past the GoAway frame's 1356 // TODO(willchan): Cancel any streams that are past the GoAway frame's
1313 // |last_accepted_stream_id|. 1357 // |last_accepted_stream_id|.
1314 1358
1315 // Don't bother killing any streams that are still reading. They'll either 1359 // Don't bother killing any streams that are still reading. They'll either
1316 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is 1360 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is
1317 // closed. 1361 // closed.
1318 } 1362 }
1319 1363
1364 void SpdySession::OnPing(const spdy::SpdyPingControlFrame& frame) {
1365 net_log_.AddEvent(
1366 NetLog::TYPE_SPDY_SESSION_PING,
1367 make_scoped_refptr(new NetLogSpdyPingParameter(frame.unique_id())));
jar (doing other things) 2011/10/14 19:59:07 We probably need to condition this on logging... e
ramant (doing other things) 2011/10/14 23:42:45 Done.
1368
1369 // Send reponse to a PING from Server.
1370 if (frame.unique_id() % 2 == 0) {
1371 WritePingFrame();
jar (doing other things) 2011/10/14 19:59:07 You need to pass the frame.unique_id
ramant (doing other things) 2011/10/14 23:42:45 Done.
1372 return;
1373 }
1374
1375 --pings_in_flight_;
1376 if (pings_in_flight_ < 0) {
1377 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true);
1378 return;
1379 }
1380
1381 if (pings_in_flight_ > 0)
1382 return;
1383
1384 if (last_sent_was_ping_)
1385 return;
1386
1387 PlanToSendPostPing();
1388 }
1389
1320 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { 1390 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) {
1321 spdy::SpdySettings settings; 1391 spdy::SpdySettings settings;
1322 if (spdy_framer_.ParseSettings(&frame, &settings)) { 1392 if (spdy_framer_.ParseSettings(&frame, &settings)) {
1323 HandleSettings(settings); 1393 HandleSettings(settings);
1324 spdy_settings_->Set(host_port_pair(), settings); 1394 spdy_settings_->Set(host_port_pair(), settings);
1325 } 1395 }
1326 1396
1327 received_settings_ = true; 1397 received_settings_ = true;
1328 1398
1329 net_log_.AddEvent( 1399 net_log_.AddEvent(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 CHECK_EQ(stream->stream_id(), stream_id); 1437 CHECK_EQ(stream->stream_id(), stream_id);
1368 1438
1369 net_log_.AddEvent( 1439 net_log_.AddEvent(
1370 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, 1440 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE,
1371 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( 1441 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter(
1372 stream_id, delta_window_size, stream->recv_window_size()))); 1442 stream_id, delta_window_size, stream->recv_window_size())));
1373 1443
1374 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( 1444 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame(
1375 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); 1445 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size));
1376 QueueFrame(window_update_frame.get(), stream->priority(), stream); 1446 QueueFrame(window_update_frame.get(), stream->priority(), stream);
1447 last_sent_was_ping_ = false;
willchan no longer on Chromium 2011/10/14 22:49:21 Why don't we just call this in QueueFrame()? You c
ramant (doing other things) 2011/10/14 23:42:45 We don't want to set last_sent_was_ping_ to true w
1377 } 1448 }
1378 1449
1379 // Given a cwnd that we would have sent to the server, modify it based on the 1450 // Given a cwnd that we would have sent to the server, modify it based on the
1380 // field trial policy. 1451 // field trial policy.
1381 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { 1452 uint32 ApplyCwndFieldTrialPolicy(int cwnd) {
1382 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); 1453 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd");
1383 if (!trial) { 1454 if (!trial) {
1384 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; 1455 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList";
1385 return cwnd; 1456 return cwnd;
1386 } 1457 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 1502
1432 net_log_.AddEvent( 1503 net_log_.AddEvent(
1433 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, 1504 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
1434 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); 1505 make_scoped_refptr(new NetLogSpdySettingsParameter(settings)));
1435 1506
1436 // Create the SETTINGS frame and send it. 1507 // Create the SETTINGS frame and send it.
1437 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( 1508 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame(
1438 spdy_framer_.CreateSettings(settings)); 1509 spdy_framer_.CreateSettings(settings));
1439 sent_settings_ = true; 1510 sent_settings_ = true;
1440 QueueFrame(settings_frame.get(), 0, NULL); 1511 QueueFrame(settings_frame.get(), 0, NULL);
1512 last_sent_was_ping_ = false;
1441 } 1513 }
1442 1514
1443 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { 1515 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) {
1444 for (spdy::SpdySettings::const_iterator i = settings.begin(), 1516 for (spdy::SpdySettings::const_iterator i = settings.begin(),
1445 end = settings.end(); i != end; ++i) { 1517 end = settings.end(); i != end; ++i) {
1446 const uint32 id = i->first.id(); 1518 const uint32 id = i->first.id();
1447 const uint32 val = i->second; 1519 const uint32 val = i->second;
1448 switch (id) { 1520 switch (id) {
1449 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: 1521 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
1450 max_concurrent_streams_ = std::min(static_cast<size_t>(val), 1522 max_concurrent_streams_ = std::min(static_cast<size_t>(val),
1451 max_concurrent_stream_limit_); 1523 max_concurrent_stream_limit_);
1452 ProcessPendingCreateStreams(); 1524 ProcessPendingCreateStreams();
1453 break; 1525 break;
1454 } 1526 }
1455 } 1527 }
1456 } 1528 }
1457 1529
1530 void SpdySession::SendPing() {
1531 if (pings_in_flight_ || post_ping_pending_ || !send_ping_for_every_request_)
willchan no longer on Chromium 2011/10/14 22:49:21 So, if we are sending a ping for every request, ho
ramant (doing other things) 2011/10/14 23:42:45 The variable name is wrong. We don't send ping for
1532 return;
1533
1534 const base::TimeDelta kInterval =
1535 base::TimeDelta::FromMilliseconds(hung_interval_ms_);
jar (doing other things) 2011/10/14 19:59:07 This needs a different timer name. It is really m
ramant (doing other things) 2011/10/14 23:42:45 Done.
1536
1537 base::TimeTicks now = base::TimeTicks::Now();
1538 // If we haven't heard from server, then send a pre-PING.
1539 if ((now - received_data_time_) > kInterval)
1540 SendPrePing();
1541
1542 PlanToSendPostPing();
1543 }
1544
1545 void SpdySession::SendPrePing() {
1546 AutoReset<bool> reset(&delayed_write_pending_, true);
willchan no longer on Chromium 2011/10/14 22:49:21 Please explain how this works. How does this coale
ramant (doing other things) 2011/10/14 23:42:45 Deleted the AutoReset. You are right, we are writ
1547 WritePingFrame();
1548 PlanToCheckStatus();
1549 ++pings_in_flight_;
jar (doing other things) 2011/10/14 19:59:07 You should pass the next_ping_id_ to WritePingFram
ramant (doing other things) 2011/10/14 23:42:45 Done.
1550 last_sent_was_ping_ = true;
1551 }
1552
1553 void SpdySession::SendPostPing() {
1554 DCHECK(post_ping_pending_);
1555 post_ping_pending_ = false;
1556 WritePingFrame();
1557 PlanToCheckStatus();
1558 ++pings_in_flight_;
1559 last_sent_was_ping_ = true;
1560 }
1561
1562 void SpdySession::PlanToSendPostPing() {
1563 if (post_ping_pending_)
1564 return;
1565
1566 post_ping_pending_ = true;
1567 MessageLoop::current()->PostDelayedTask(
1568 FROM_HERE,
1569 method_factory_.NewRunnableMethod(&SpdySession::SendPostPing),
1570 post_ping_delay_time_ms_);
1571 }
1572
1573 void SpdySession::PlanToCheckStatus() {
1574 if (check_status_pending_)
1575 return;
1576
1577 check_status_pending_ = true;
1578 MessageLoop::current()->PostDelayedTask(
1579 FROM_HERE,
1580 method_factory_.NewRunnableMethod(
1581 &SpdySession::CheckStatus, base::TimeTicks::Now()),
1582 check_status_delay_time_ms_);
jar (doing other things) 2011/10/14 19:59:07 This should be our hung_interval_ms (or newer name
ramant (doing other things) 2011/10/14 23:42:45 Done.
1583 }
1584
1585 void SpdySession::WritePingFrame() {
1586 scoped_ptr<spdy::SpdyPingControlFrame> ping_frame(
1587 spdy_framer_.CreatePingFrame(unique_id_counter_));
1588 QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, NULL);
1589
1590 if (net_log().IsLoggingAllEvents()) {
1591 net_log().AddEvent(
1592 NetLog::TYPE_SPDY_SESSION_PING,
1593 make_scoped_refptr(new NetLogSpdyPingParameter(unique_id_counter_)));
1594 }
1595 unique_id_counter_ += 2;
jar (doing other things) 2011/10/14 19:59:07 This is only done if we were sending (an odd numbe
ramant (doing other things) 2011/10/14 23:42:45 Done.
1596 }
1597
1598 void SpdySession::CheckStatus(base::TimeTicks last_check_time) {
1599 // Check if we got a response back for all PINGs we had sent.
1600 if (pings_in_flight_ == 0) {
1601 check_status_pending_ = false;
1602 return;
1603 }
1604
1605 DCHECK(check_status_pending_);
1606
1607 const base::TimeDelta kHungInterval =
1608 base::TimeDelta::FromMilliseconds(hung_interval_ms_);
1609 if (received_data_time_ < last_check_time) {
1610 DCHECK(base::TimeTicks::Now() - received_data_time_ > kHungInterval);
jar (doing other things) 2011/10/14 19:59:07 I think this should be >= kHungInterval
willchan no longer on Chromium 2011/10/14 23:13:11 Can you use DCHECK_GT?
ramant (doing other things) 2011/10/14 23:42:45 Done.
ramant (doing other things) 2011/10/14 23:42:45 DCHECK_GE was giving errors for TimeDelta argument
1611 CloseSessionOnError(net::ERR_SPDY_PING_FAILED, true);
1612 return;
1613 }
1614
1615 // Check the status of connection after a delay.
1616 base::TimeTicks now = base::TimeTicks::Now();
jar (doing other things) 2011/10/14 19:59:07 You mentioned this code might be clearer if you ju
ramant (doing other things) 2011/10/14 23:42:45 Done.
1617 base::TimeDelta delay = kHungInterval - (now - received_data_time_);
1618 MessageLoop::current()->PostDelayedTask(
1619 FROM_HERE,
1620 method_factory_.NewRunnableMethod(&SpdySession::CheckStatus, now),
1621 delay.InMilliseconds());
1622 }
1623
1458 void SpdySession::RecordHistograms() { 1624 void SpdySession::RecordHistograms() {
1459 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", 1625 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession",
1460 streams_initiated_count_, 1626 streams_initiated_count_,
1461 0, 300, 50); 1627 0, 300, 50);
1462 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", 1628 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession",
1463 streams_pushed_count_, 1629 streams_pushed_count_,
1464 0, 300, 50); 1630 0, 300, 50);
1465 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", 1631 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession",
1466 streams_pushed_and_claimed_count_, 1632 streams_pushed_and_claimed_count_,
1467 0, 300, 50); 1633 0, 300, 50);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 if (it == pending_callback_map_.end()) 1702 if (it == pending_callback_map_.end())
1537 return; 1703 return;
1538 1704
1539 OldCompletionCallback* callback = it->second.callback; 1705 OldCompletionCallback* callback = it->second.callback;
1540 int result = it->second.result; 1706 int result = it->second.result;
1541 pending_callback_map_.erase(it); 1707 pending_callback_map_.erase(it);
1542 callback->Run(result); 1708 callback->Run(result);
1543 } 1709 }
1544 1710
1545 } // namespace net 1711 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698