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

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

Issue 10815074: Instead of enqueueing SPDY frames, enqueue SPDY streams that are ready to produce data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove logging and cleanup Created 8 years, 5 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
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_stream_spdy2_unittest.cc » ('j') | 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) 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_stream.h" 5 #include "net/spdy/spdy_stream.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 if (*i >= 'A' && *i <= 'Z') { 43 if (*i >= 'A' && *i <= 'Z') {
44 return true; 44 return true;
45 } 45 }
46 } 46 }
47 return false; 47 return false;
48 } 48 }
49 49
50 } // namespace 50 } // namespace
51 51
52 SpdyStream::SpdyStream(SpdySession* session, 52 SpdyStream::SpdyStream(SpdySession* session,
53 SpdyStreamId stream_id,
54 bool pushed, 53 bool pushed,
55 const BoundNetLog& net_log) 54 const BoundNetLog& net_log)
56 : continue_buffering_data_(true), 55 : continue_buffering_data_(true),
57 stream_id_(stream_id), 56 stream_id_(0),
58 priority_(HIGHEST), 57 priority_(HIGHEST),
59 slot_(0), 58 slot_(0),
60 stalled_by_flow_control_(false), 59 stalled_by_flow_control_(false),
61 send_window_size_(kSpdyStreamInitialWindowSize), 60 send_window_size_(kSpdyStreamInitialWindowSize),
62 recv_window_size_(kSpdyStreamInitialWindowSize), 61 recv_window_size_(kSpdyStreamInitialWindowSize),
63 unacked_recv_window_bytes_(0), 62 unacked_recv_window_bytes_(0),
64 pushed_(pushed), 63 pushed_(pushed),
65 response_received_(false), 64 response_received_(false),
66 session_(session), 65 session_(session),
67 delegate_(NULL), 66 delegate_(NULL),
68 request_time_(base::Time::Now()), 67 request_time_(base::Time::Now()),
69 response_(new SpdyHeaderBlock), 68 response_(new SpdyHeaderBlock),
70 io_state_(STATE_NONE), 69 io_state_(STATE_NONE),
71 response_status_(OK), 70 response_status_(OK),
72 cancelled_(false), 71 cancelled_(false),
73 has_upload_data_(false), 72 has_upload_data_(false),
74 net_log_(net_log), 73 net_log_(net_log),
75 send_bytes_(0), 74 send_bytes_(0),
76 recv_bytes_(0), 75 recv_bytes_(0),
77 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE) { 76 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE) {
78 } 77 }
79 78
79 class SpdyStream::SpdyStreamIOBufferProducer
80 : public SpdySession::SpdyIOBufferProducer {
81 public:
82 SpdyStreamIOBufferProducer(SpdyStream* stream) : stream_(stream) {}
83
84 // SpdyFrameProducer
85 virtual RequestPriority GetPriority() const OVERRIDE {
86 return stream_->priority();
87 }
88
89 virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) OVERRIDE {
90 if (stream_->stream_id() == 0)
91 SpdySession::SpdyIOBufferProducer::ActivateStream(session, stream_);
92 frame_.reset(stream_->ProduceNextFrame());
93 return frame_ == NULL ? NULL :
94 SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
95 frame_.get(), GetPriority(), stream_);
96 }
97
98 private:
99 scoped_refptr<SpdyStream> stream_;
100 scoped_ptr<SpdyFrame> frame_;
101 };
102
103 void SpdyStream::SetHasWriteAvailable() {
104 session_->SetStreamHasWriteAvailable(this,
105 new SpdyStreamIOBufferProducer(this));
106 }
107
108 SpdyFrame* SpdyStream::ProduceNextFrame() {
109 if (io_state_ == STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE) {
110 CHECK(request_.get());
111 CHECK_GT(stream_id_, 0u);
112
113 std::string origin = GetUrl().GetOrigin().spec();
114 DCHECK(origin[origin.length() - 1] == '/');
115 origin.erase(origin.length() - 1); // Trim trailing slash.
116 SpdyCredentialControlFrame* frame = session_->CreateCredentialFrame(
117 origin, domain_bound_cert_type_, domain_bound_private_key_,
118 domain_bound_cert_, priority_);
119 return frame;
120 } else if (io_state_ == STATE_SEND_HEADERS_COMPLETE) {
121 CHECK(request_.get());
122 CHECK_GT(stream_id_, 0u);
123
124 SpdyControlFlags flags =
125 has_upload_data_ ? CONTROL_FLAG_NONE : CONTROL_FLAG_FIN;
126 SpdySynStreamControlFrame* frame = session_->CreateSynStream(
127 stream_id_, priority_, slot_, flags, *request_);
128 send_time_ = base::TimeTicks::Now();
129 return frame;
130 } else {
131 CHECK(!cancelled());
132 // We must need to write stream data.
133 // Until the headers have been completely sent, we can not be sure
134 // that our stream_id is correct.
135 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
136 DCHECK_GT(stream_id_, 0u);
137 DCHECK(!pending_data_frames_.empty());
138 SpdyFrame* frame = pending_data_frames_.front();
139 pending_data_frames_.pop_front();
140 return frame;
141 }
142 }
143
80 SpdyStream::~SpdyStream() { 144 SpdyStream::~SpdyStream() {
81 UpdateHistograms(); 145 UpdateHistograms();
146 while (!pending_data_frames_.empty()) {
147 SpdyFrame* frame = pending_data_frames_.back();
148 pending_data_frames_.pop_back();
149 delete frame;
150 }
82 } 151 }
83 152
84 void SpdyStream::SetDelegate(Delegate* delegate) { 153 void SpdyStream::SetDelegate(Delegate* delegate) {
85 CHECK(delegate); 154 CHECK(delegate);
86 delegate_ = delegate; 155 delegate_ = delegate;
87 156
88 if (pushed_) { 157 if (pushed_) {
89 CHECK(response_received()); 158 CHECK(response_received());
90 MessageLoop::current()->PostTask( 159 MessageLoop::current()->PostTask(
91 FROM_HERE, base::Bind(&SpdyStream::PushedStreamReplayData, this)); 160 FROM_HERE, base::Bind(&SpdyStream::PushedStreamReplayData, this));
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 void SpdyStream::Cancel() { 522 void SpdyStream::Cancel() {
454 if (cancelled()) 523 if (cancelled())
455 return; 524 return;
456 525
457 cancelled_ = true; 526 cancelled_ = true;
458 if (session_->IsStreamActive(stream_id_)) 527 if (session_->IsStreamActive(stream_id_))
459 session_->ResetStream(stream_id_, CANCEL, ""); 528 session_->ResetStream(stream_id_, CANCEL, "");
460 } 529 }
461 530
462 void SpdyStream::Close() { 531 void SpdyStream::Close() {
463 session_->CloseStream(stream_id_, net::OK); 532 if (stream_id_ != 0)
533 session_->CloseStream(stream_id_, net::OK);
534 else
535 session_->CloseCreatedStream(this, OK);
464 } 536 }
465 537
466 int SpdyStream::SendRequest(bool has_upload_data) { 538 int SpdyStream::SendRequest(bool has_upload_data) {
467 // Pushed streams do not send any data, and should always be in STATE_OPEN or 539 // Pushed streams do not send any data, and should always be in STATE_OPEN or
468 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push 540 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push
469 // behavior. 541 // behavior.
470 has_upload_data_ = has_upload_data; 542 has_upload_data_ = has_upload_data;
471 if (pushed_) { 543 if (pushed_) {
472 send_time_ = base::TimeTicks::Now(); 544 send_time_ = base::TimeTicks::Now();
473 DCHECK(!has_upload_data_); 545 DCHECK(!has_upload_data_);
474 DCHECK(response_received()); 546 DCHECK(response_received());
475 return ERR_IO_PENDING; 547 return ERR_IO_PENDING;
476 } 548 }
477 CHECK_EQ(STATE_NONE, io_state_); 549 CHECK_EQ(STATE_NONE, io_state_);
478 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; 550 io_state_ = STATE_GET_DOMAIN_BOUND_CERT;
479 return DoLoop(OK); 551 return DoLoop(OK);
480 } 552 }
481 553
482 int SpdyStream::WriteStreamData(IOBuffer* data, int length, 554 int SpdyStream::WriteStreamData(IOBuffer* data, int length,
483 SpdyDataFlags flags) { 555 SpdyDataFlags flags) {
484 // Until the headers have been completely sent, we can not be sure 556 // Until the headers have been completely sent, we can not be sure
485 // that our stream_id is correct. 557 // that our stream_id is correct.
486 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE); 558 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
487 return session_->WriteStreamData(stream_id_, data, length, flags); 559 CHECK_GT(stream_id_, 0u);
560
561 pending_data_frames_.push_back(
562 session_->CreateDataFrame(stream_id_, data, length, flags));
563
564 SetHasWriteAvailable();
565 return ERR_IO_PENDING;
488 } 566 }
489 567
490 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, 568 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info,
491 bool* was_npn_negotiated, 569 bool* was_npn_negotiated,
492 NextProto* protocol_negotiated) { 570 NextProto* protocol_negotiated) {
493 return session_->GetSSLInfo( 571 return session_->GetSSLInfo(
494 ssl_info, was_npn_negotiated, protocol_negotiated); 572 ssl_info, was_npn_negotiated, protocol_negotiated);
495 } 573 }
496 574
497 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) { 575 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 return result; 699 return result;
622 700
623 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT; 701 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT;
624 slot_ = session_->credential_state()->SetHasCredential(GetUrl()); 702 slot_ = session_->credential_state()->SetHasCredential(GetUrl());
625 return OK; 703 return OK;
626 } 704 }
627 705
628 int SpdyStream::DoSendDomainBoundCert() { 706 int SpdyStream::DoSendDomainBoundCert() {
629 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE; 707 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE;
630 CHECK(request_.get()); 708 CHECK(request_.get());
631 std::string origin = GetUrl().GetOrigin().spec(); 709 SetHasWriteAvailable();
632 origin.erase(origin.length() - 1); // trim trailing slash 710 return ERR_IO_PENDING;
633 int rv = session_->WriteCredentialFrame(
634 origin, domain_bound_cert_type_, domain_bound_private_key_,
635 domain_bound_cert_, priority_);
636 if (rv != ERR_IO_PENDING)
637 return rv;
638 return OK;
639 } 711 }
640 712
641 int SpdyStream::DoSendDomainBoundCertComplete(int result) { 713 int SpdyStream::DoSendDomainBoundCertComplete(int result) {
642 if (result < 0) 714 if (result < 0)
643 return result; 715 return result;
644 716
645 io_state_ = STATE_SEND_HEADERS; 717 io_state_ = STATE_SEND_HEADERS;
646 return OK; 718 return OK;
647 } 719 }
648 720
649 int SpdyStream::DoSendHeaders() { 721 int SpdyStream::DoSendHeaders() {
650 CHECK(!cancelled_); 722 CHECK(!cancelled_);
651 723
652 SpdyControlFlags flags = CONTROL_FLAG_NONE; 724 SetHasWriteAvailable();
653 if (!has_upload_data_)
654 flags = CONTROL_FLAG_FIN;
655
656 CHECK(request_.get());
657 int result = session_->WriteSynStream(
658 stream_id_, priority_, slot_, flags,
659 *request_);
660 if (result != ERR_IO_PENDING)
661 return result;
662
663 send_time_ = base::TimeTicks::Now();
664 io_state_ = STATE_SEND_HEADERS_COMPLETE; 725 io_state_ = STATE_SEND_HEADERS_COMPLETE;
665 return ERR_IO_PENDING; 726 return ERR_IO_PENDING;
666 } 727 }
667 728
668 int SpdyStream::DoSendHeadersComplete(int result) { 729 int SpdyStream::DoSendHeadersComplete(int result) {
669 if (result < 0) 730 if (result < 0)
670 return result; 731 return result;
671 732
672 CHECK_GT(result, 0); 733 CHECK_GT(result, 0);
673 734
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", 794 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime",
734 recv_last_byte_time_ - recv_first_byte_time_); 795 recv_last_byte_time_ - recv_first_byte_time_);
735 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", 796 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime",
736 recv_last_byte_time_ - send_time_); 797 recv_last_byte_time_ - send_time_);
737 798
738 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); 799 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_);
739 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); 800 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_);
740 } 801 }
741 802
742 } // namespace net 803 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_stream_spdy2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698