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

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
« net/base/net_log_event_type_list.h ('K') | « net/spdy/spdy_session.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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() {}
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 max_concurrent_streams_(kDefaultMaxConcurrentStreams), 254 max_concurrent_streams_(kDefaultMaxConcurrentStreams),
237 streams_initiated_count_(0), 255 streams_initiated_count_(0),
238 streams_pushed_count_(0), 256 streams_pushed_count_(0),
239 streams_pushed_and_claimed_count_(0), 257 streams_pushed_and_claimed_count_(0),
240 streams_abandoned_count_(0), 258 streams_abandoned_count_(0),
241 frames_received_(0), 259 frames_received_(0),
242 bytes_received_(0), 260 bytes_received_(0),
243 sent_settings_(false), 261 sent_settings_(false),
244 received_settings_(false), 262 received_settings_(false),
245 stalled_streams_(0), 263 stalled_streams_(0),
264 pings_in_flight_(0),
265 unique_id_counter_(1),
266 follower_ping_pending_(false),
246 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), 267 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize),
247 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), 268 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize),
248 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), 269 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
249 verify_domain_authentication_(verify_domain_authentication) { 270 verify_domain_authentication_(verify_domain_authentication) {
250 DCHECK(HttpStreamFactory::spdy_enabled()); 271 DCHECK(HttpStreamFactory::spdy_enabled());
251 net_log_.BeginEvent( 272 net_log_.BeginEvent(
252 NetLog::TYPE_SPDY_SESSION, 273 NetLog::TYPE_SPDY_SESSION,
253 make_scoped_refptr( 274 make_scoped_refptr(
254 new NetLogSpdySessionParameter(host_port_proxy_pair_))); 275 new NetLogSpdySessionParameter(host_port_proxy_pair_)));
255 276
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 spdy::SpdyStreamId stream_id, 485 spdy::SpdyStreamId stream_id,
465 RequestPriority priority, 486 RequestPriority priority,
466 spdy::SpdyControlFlags flags, 487 spdy::SpdyControlFlags flags,
467 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { 488 const linked_ptr<spdy::SpdyHeaderBlock>& headers) {
468 // Find our stream 489 // Find our stream
469 if (!IsStreamActive(stream_id)) 490 if (!IsStreamActive(stream_id))
470 return ERR_INVALID_SPDY_STREAM; 491 return ERR_INVALID_SPDY_STREAM;
471 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; 492 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
472 CHECK_EQ(stream->stream_id(), stream_id); 493 CHECK_EQ(stream->stream_id(), stream_id);
473 494
495 int result = SendPing(stream_id);
willchan no longer on Chromium 2011/10/13 06:38:39 You should queue this _after_ the SYN_STREAM. We d
willchan no longer on Chromium 2011/10/13 15:47:17 You didn't address this comment.
ramant (doing other things) 2011/10/13 21:41:14 Jim said Roberto wanted us to send the pre-ping re
496 if (result != ERR_IO_PENDING)
497 return result;
498
474 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame( 499 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame(
475 spdy_framer_.CreateSynStream( 500 spdy_framer_.CreateSynStream(
476 stream_id, 0, 501 stream_id, 0,
477 ConvertRequestPriorityToSpdyPriority(priority), 502 ConvertRequestPriorityToSpdyPriority(priority),
478 flags, false, headers.get())); 503 flags, false, headers.get()));
479 QueueFrame(syn_frame.get(), priority, stream); 504 QueueFrame(syn_frame.get(), priority, stream);
480 505
481 base::StatsCounter spdy_requests("spdy.requests"); 506 base::StatsCounter spdy_requests("spdy.requests");
482 spdy_requests.Increment(); 507 spdy_requests.Increment();
483 streams_initiated_count_++; 508 streams_initiated_count_++;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 // Session is tearing down. 627 // Session is tearing down.
603 net::Error error = static_cast<net::Error>(bytes_read); 628 net::Error error = static_cast<net::Error>(bytes_read);
604 if (bytes_read == 0) 629 if (bytes_read == 0)
605 error = ERR_CONNECTION_CLOSED; 630 error = ERR_CONNECTION_CLOSED;
606 CloseSessionOnError(error, true); 631 CloseSessionOnError(error, true);
607 return; 632 return;
608 } 633 }
609 634
610 bytes_received_ += bytes_read; 635 bytes_received_ += bytes_read;
611 636
637 received_data_time_ = base::TimeTicks::Now();
638
612 // The SpdyFramer will use callbacks onto |this| as it parses frames. 639 // The SpdyFramer will use callbacks onto |this| as it parses frames.
613 // When errors occur, those callbacks can lead to teardown of all references 640 // When errors occur, those callbacks can lead to teardown of all references
614 // to |this|, so maintain a reference to self during this call for safe 641 // to |this|, so maintain a reference to self during this call for safe
615 // cleanup. 642 // cleanup.
616 scoped_refptr<SpdySession> self(this); 643 scoped_refptr<SpdySession> self(this);
617 644
618 char *data = read_buffer_->data(); 645 char *data = read_buffer_->data();
619 while (bytes_read && 646 while (bytes_read &&
620 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) { 647 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) {
621 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read); 648 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read);
622 bytes_read -= bytes_processed; 649 bytes_read -= bytes_processed;
623 data += bytes_processed; 650 data += bytes_processed;
624 if (spdy_framer_.state() == spdy::SpdyFramer::SPDY_DONE) 651 if (spdy_framer_.state() == spdy::SpdyFramer::SPDY_DONE)
625 spdy_framer_.Reset(); 652 spdy_framer_.Reset();
626 } 653 }
627 654
628 if (state_ != CLOSED) 655 if (state_ != CLOSED)
629 ReadSocket(); 656 ReadSocket();
630 } 657 }
631 658
632 void SpdySession::OnWriteComplete(int result) { 659 void SpdySession::OnWriteComplete(int result) {
660 OnWriteCompleteInternal(result, false);
661 }
662
663 void SpdySession::OnWriteCompleteInternal(int result, bool ping_frame) {
willchan no longer on Chromium 2011/10/13 06:38:39 You shouldn't need this extra bool parameter.
ramant (doing other things) 2011/10/13 21:41:14 Done.
633 DCHECK(write_pending_); 664 DCHECK(write_pending_);
634 DCHECK(in_flight_write_.size()); 665 DCHECK(in_flight_write_.size());
635 666
636 write_pending_ = false; 667 write_pending_ = false;
637 668
638 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); 669 scoped_refptr<SpdyStream> stream = in_flight_write_.stream();
639 670
640 if (result >= 0) { 671 if (result >= 0) {
641 // It should not be possible to have written more bytes than our 672 // It should not be possible to have written more bytes than our
642 // in_flight_write_. 673 // in_flight_write_.
643 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); 674 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining());
644 675
645 in_flight_write_.buffer()->DidConsume(result); 676 in_flight_write_.buffer()->DidConsume(result);
646 677
647 // We only notify the stream when we've fully written the pending frame. 678 // We only notify the stream when we've fully written the pending frame.
648 if (!in_flight_write_.buffer()->BytesRemaining()) { 679 if (!in_flight_write_.buffer()->BytesRemaining()) {
649 if (stream) { 680 if (stream) {
650 // Report the number of bytes written to the caller, but exclude the 681 // Report the number of bytes written to the caller, but exclude the
651 // frame size overhead. NOTE: if this frame was compressed the 682 // frame size overhead. NOTE: if this frame was compressed the
652 // reported bytes written is the compressed size, not the original 683 // reported bytes written is the compressed size, not the original
653 // size. 684 // size.
654 if (result > 0) { 685 if (result > 0) {
655 result = in_flight_write_.buffer()->size(); 686 result = in_flight_write_.buffer()->size();
656 DCHECK_GE(result, static_cast<int>(spdy::SpdyFrame::size())); 687 DCHECK_GE(result, static_cast<int>(spdy::SpdyFrame::size()));
657 result -= static_cast<int>(spdy::SpdyFrame::size()); 688 result -= static_cast<int>(spdy::SpdyFrame::size());
658 } 689 }
659 690
660 // It is possible that the stream was cancelled while we were writing 691 // It is possible that the stream was cancelled while we were writing
661 // to the socket. 692 // to the socket.
662 if (!stream->cancelled()) 693 if (!stream->cancelled() && !ping_frame)
663 stream->OnWriteComplete(result); 694 stream->OnWriteComplete(result);
664 } 695 }
665 696
666 // Cleanup the write which just completed. 697 // Cleanup the write which just completed.
667 in_flight_write_.release(); 698 in_flight_write_.release();
668 } 699 }
669 700
670 // Write more data. We're already in a continuation, so we can 701 // Write more data. We're already in a continuation, so we can
671 // go ahead and write it immediately (without going back to the 702 // go ahead and write it immediately (without going back to the
672 // message loop). 703 // message loop).
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 // closed, just return. 770 // closed, just return.
740 if (state_ < CONNECTED || state_ == CLOSED) 771 if (state_ < CONNECTED || state_ == CLOSED)
741 return; 772 return;
742 773
743 if (write_pending_) // Another write is in progress still. 774 if (write_pending_) // Another write is in progress still.
744 return; 775 return;
745 776
746 // Loop sending frames until we've sent everything or until the write 777 // Loop sending frames until we've sent everything or until the write
747 // returns error (or ERR_IO_PENDING). 778 // returns error (or ERR_IO_PENDING).
748 while (in_flight_write_.buffer() || !queue_.empty()) { 779 while (in_flight_write_.buffer() || !queue_.empty()) {
780 bool ping_frame = false;
willchan no longer on Chromium 2011/10/13 06:38:39 You shouldn't need this.
ramant (doing other things) 2011/10/13 21:41:14 Done.
749 if (!in_flight_write_.buffer()) { 781 if (!in_flight_write_.buffer()) {
750 // Grab the next SpdyFrame to send. 782 // Grab the next SpdyFrame to send.
751 SpdyIOBuffer next_buffer = queue_.top(); 783 SpdyIOBuffer next_buffer = queue_.top();
752 queue_.pop(); 784 queue_.pop();
753 785
754 // We've deferred compression until just before we write it to the socket, 786 // We've deferred compression until just before we write it to the socket,
755 // which is now. At this time, we don't compress our data frames. 787 // which is now. At this time, we don't compress our data frames.
756 spdy::SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false); 788 spdy::SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
757 size_t size; 789 size_t size;
758 if (spdy_framer_.IsCompressible(uncompressed_frame)) { 790 if (spdy_framer_.IsCompressible(uncompressed_frame)) {
(...skipping 11 matching lines...) Expand all
770 802
771 // TODO(mbelshe): We have too much copying of data here. 803 // TODO(mbelshe): We have too much copying of data here.
772 IOBufferWithSize* buffer = new IOBufferWithSize(size); 804 IOBufferWithSize* buffer = new IOBufferWithSize(size);
773 memcpy(buffer->data(), compressed_frame->data(), size); 805 memcpy(buffer->data(), compressed_frame->data(), size);
774 806
775 // Attempt to send the frame. 807 // Attempt to send the frame.
776 in_flight_write_ = SpdyIOBuffer(buffer, size, 0, next_buffer.stream()); 808 in_flight_write_ = SpdyIOBuffer(buffer, size, 0, next_buffer.stream());
777 } else { 809 } else {
778 size = uncompressed_frame.length() + spdy::SpdyFrame::size(); 810 size = uncompressed_frame.length() + spdy::SpdyFrame::size();
779 in_flight_write_ = next_buffer; 811 in_flight_write_ = next_buffer;
812 if (spdy_framer_.IsPingFrame(uncompressed_frame))
813 ping_frame = true;
780 } 814 }
781 } else { 815 } else {
782 DCHECK(in_flight_write_.buffer()->BytesRemaining()); 816 DCHECK(in_flight_write_.buffer()->BytesRemaining());
783 } 817 }
784 818
785 write_pending_ = true; 819 write_pending_ = true;
786 int rv = connection_->socket()->Write(in_flight_write_.buffer(), 820 int rv = connection_->socket()->Write(in_flight_write_.buffer(),
787 in_flight_write_.buffer()->BytesRemaining(), &write_callback_); 821 in_flight_write_.buffer()->BytesRemaining(), &write_callback_);
788 if (rv == net::ERR_IO_PENDING) 822 if (rv == net::ERR_IO_PENDING)
789 break; 823 break;
790 824
791 // We sent the frame successfully. 825 // We sent the frame successfully.
792 OnWriteComplete(rv); 826 OnWriteCompleteInternal(rv, ping_frame);
793 827
794 // TODO(mbelshe): Test this error case. Maybe we should mark the socket 828 // TODO(mbelshe): Test this error case. Maybe we should mark the socket
795 // as in an error state. 829 // as in an error state.
796 if (rv < 0) 830 if (rv < 0)
797 break; 831 break;
798 } 832 }
799 } 833 }
800 834
801 void SpdySession::CloseAllStreams(net::Error status) { 835 void SpdySession::CloseAllStreams(net::Error status) {
802 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); 836 base::StatsCounter abandoned_streams("spdy.abandoned_streams");
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 return; 1253 return;
1220 } 1254 }
1221 } 1255 }
1222 1256
1223 frames_received_++; 1257 frames_received_++;
1224 1258
1225 switch (type) { 1259 switch (type) {
1226 case spdy::GOAWAY: 1260 case spdy::GOAWAY:
1227 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); 1261 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame));
1228 break; 1262 break;
1263 case spdy::PING:
1264 OnPing(*reinterpret_cast<const spdy::SpdyPingControlFrame*>(frame));
1265 break;
1229 case spdy::SETTINGS: 1266 case spdy::SETTINGS:
1230 OnSettings( 1267 OnSettings(
1231 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); 1268 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame));
1232 break; 1269 break;
1233 case spdy::RST_STREAM: 1270 case spdy::RST_STREAM:
1234 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); 1271 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame));
1235 break; 1272 break;
1236 case spdy::SYN_STREAM: 1273 case spdy::SYN_STREAM:
1237 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), 1274 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame),
1238 headers); 1275 headers);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 CloseAllStreams(net::ERR_ABORTED); 1344 CloseAllStreams(net::ERR_ABORTED);
1308 1345
1309 // TODO(willchan): Cancel any streams that are past the GoAway frame's 1346 // TODO(willchan): Cancel any streams that are past the GoAway frame's
1310 // |last_accepted_stream_id|. 1347 // |last_accepted_stream_id|.
1311 1348
1312 // Don't bother killing any streams that are still reading. They'll either 1349 // Don't bother killing any streams that are still reading. They'll either
1313 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is 1350 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is
1314 // closed. 1351 // closed.
1315 } 1352 }
1316 1353
1354 void SpdySession::OnPing(const spdy::SpdyPingControlFrame& frame) {
1355 --pings_in_flight_;
1356 net_log_.AddEvent(
1357 NetLog::TYPE_SPDY_SESSION_PING,
1358 make_scoped_refptr(new NetLogSpdyPingParameter(frame.unique_id())));
1359 }
1360
1317 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { 1361 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) {
1318 spdy::SpdySettings settings; 1362 spdy::SpdySettings settings;
1319 if (spdy_framer_.ParseSettings(&frame, &settings)) { 1363 if (spdy_framer_.ParseSettings(&frame, &settings)) {
1320 HandleSettings(settings); 1364 HandleSettings(settings);
1321 spdy_settings_->Set(host_port_pair(), settings); 1365 spdy_settings_->Set(host_port_pair(), settings);
1322 } 1366 }
1323 1367
1324 received_settings_ = true; 1368 received_settings_ = true;
1325 1369
1326 net_log_.AddEvent( 1370 net_log_.AddEvent(
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 switch (id) { 1489 switch (id) {
1446 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: 1490 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
1447 max_concurrent_streams_ = std::min(static_cast<size_t>(val), 1491 max_concurrent_streams_ = std::min(static_cast<size_t>(val),
1448 max_concurrent_stream_limit_); 1492 max_concurrent_stream_limit_);
1449 ProcessPendingCreateStreams(); 1493 ProcessPendingCreateStreams();
1450 break; 1494 break;
1451 } 1495 }
1452 } 1496 }
1453 } 1497 }
1454 1498
1499 int SpdySession::SendPing(spdy::SpdyStreamId stream_id) {
1500 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(10000);
willchan no longer on Chromium 2011/10/13 06:38:39 Wow, this logic is not what we had discussed in th
willchan no longer on Chromium 2011/10/13 15:10:53 From Raman: """ pre-PING and post-PING came after
ramant (doing other things) 2011/10/13 21:41:14 Sorry about that.
1501
1502 base::TimeTicks now = base::TimeTicks::Now();
1503 // If there are no PINGs in flight and we haven't heard from server, then
1504 // send a pre-PING.
1505 if ((pings_in_flight_ == 0) && ((now - received_data_time_) > kInterval)) {
1506 int result = SendPrePing(stream_id);
1507 if (result != ERR_IO_PENDING)
1508 return result;
1509 }
1510
1511 // Send a post-PING after a delay to make sure request has been received by
1512 // the server.
1513 const int kRequestTimeMs = 5000;
1514 if (!follower_ping_pending_) {
1515 follower_ping_pending_ = true;
1516 MessageLoop::current()->PostDelayedTask(
1517 FROM_HERE,
1518 method_factory_.NewRunnableMethod(
1519 &SpdySession::SendPostPing, stream_id),
1520 kRequestTimeMs);
1521
1522 // Post a task to check the status of the connection.
1523 const int kCheckStatusTimeMs = 10000;
1524 MessageLoop::current()->PostDelayedTask(
1525 FROM_HERE,
1526 method_factory_.NewRunnableMethod(
1527 &SpdySession::CheckStatus, stream_id, now),
1528 kCheckStatusTimeMs);
1529 }
1530 return ERR_IO_PENDING;
1531 }
1532
1533 int SpdySession::SendPrePing(spdy::SpdyStreamId stream_id) {
1534 // Delay the writing of the PING frame so that it goes along with other
1535 // frames.
1536 AutoReset<bool> reset(&delayed_write_pending_, true);
1537 return WritePingFrame(stream_id);
1538 }
1539
1540 int SpdySession::SendPostPing(spdy::SpdyStreamId stream_id) {
1541 DCHECK(follower_ping_pending_);
1542 follower_ping_pending_ = false;
1543 return WritePingFrame(stream_id);
1544 }
1545
1546 int SpdySession::WritePingFrame(spdy::SpdyStreamId stream_id) {
1547 // Find our stream.
1548 if (!IsStreamActive(stream_id))
1549 return ERR_INVALID_SPDY_STREAM;
1550 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
1551 CHECK_EQ(stream->stream_id(), stream_id);
1552
1553 scoped_ptr<spdy::SpdyPingControlFrame> ping_frame(
1554 spdy_framer_.CreatePingFrame(unique_id_counter_));
1555 QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, stream);
willchan no longer on Chromium 2011/10/13 06:38:39 Here's the problem. Pass a NULL stream to QueueFra
ramant (doing other things) 2011/10/13 21:41:14 Done.
1556
1557 if (net_log().IsLoggingAllEvents()) {
1558 net_log().AddEvent(
1559 NetLog::TYPE_SPDY_SESSION_PING,
1560 make_scoped_refptr(new NetLogSpdyPingParameter(unique_id_counter_)));
1561 }
1562
1563 ++pings_in_flight_;
1564 unique_id_counter_ += 2;
1565 return ERR_IO_PENDING;
1566 }
1567
1568 void SpdySession::CheckStatus(spdy::SpdyStreamId stream_id,
1569 base::TimeTicks last_check_time) {
1570 // Find our stream.
1571 if (!IsStreamActive(stream_id))
1572 return;
1573 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
1574 CHECK_EQ(stream->stream_id(), stream_id);
1575
1576 // Check if we got a response back for all PINGs we had sent.
1577 if (pings_in_flight_ == 0)
1578 return;
1579
1580 // Check if we haven't received any data in |kHungInterval|.
1581 const base::TimeDelta kHungInterval = base::TimeDelta::FromSeconds(10);
1582 if (received_data_time_ < last_check_time) {
1583 DCHECK(base::TimeTicks::Now() - received_data_time_ > kHungInterval);
1584 DeleteStream(stream_id, ERR_SPDY_PING_FAILED);
1585 return;
1586 }
1587
1588 // Check the status of connection after a delay.
1589 base::TimeTicks now = base::TimeTicks::Now();
1590 base::TimeDelta delay = now - received_data_time_ + kHungInterval;
1591 MessageLoop::current()->PostDelayedTask(
1592 FROM_HERE,
1593 method_factory_.NewRunnableMethod(
1594 &SpdySession::CheckStatus, stream_id, now),
1595 delay.InMilliseconds());
1596 }
1597
1455 void SpdySession::RecordHistograms() { 1598 void SpdySession::RecordHistograms() {
1456 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", 1599 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession",
1457 streams_initiated_count_, 1600 streams_initiated_count_,
1458 0, 300, 50); 1601 0, 300, 50);
1459 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", 1602 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession",
1460 streams_pushed_count_, 1603 streams_pushed_count_,
1461 0, 300, 50); 1604 0, 300, 50);
1462 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", 1605 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession",
1463 streams_pushed_and_claimed_count_, 1606 streams_pushed_and_claimed_count_,
1464 0, 300, 50); 1607 0, 300, 50);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 if (it == pending_callback_map_.end()) 1676 if (it == pending_callback_map_.end())
1534 return; 1677 return;
1535 1678
1536 OldCompletionCallback* callback = it->second.callback; 1679 OldCompletionCallback* callback = it->second.callback;
1537 int result = it->second.result; 1680 int result = it->second.result;
1538 pending_callback_map_.erase(it); 1681 pending_callback_map_.erase(it);
1539 callback->Run(result); 1682 callback->Run(result);
1540 } 1683 }
1541 1684
1542 } // namespace net 1685 } // namespace net
OLDNEW
« net/base/net_log_event_type_list.h ('K') | « net/spdy/spdy_session.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698