Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |