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

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

Issue 15740018: [SPDY] Change SpdyStream::QueueStreamData() To SendStreamData() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix comment Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_stream.h" 5 #include "net/spdy/spdy_stream.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 priority_(priority), 122 priority_(priority),
123 slot_(0), 123 slot_(0),
124 send_stalled_by_flow_control_(false), 124 send_stalled_by_flow_control_(false),
125 send_window_size_(initial_send_window_size), 125 send_window_size_(initial_send_window_size),
126 recv_window_size_(initial_recv_window_size), 126 recv_window_size_(initial_recv_window_size),
127 unacked_recv_window_bytes_(0), 127 unacked_recv_window_bytes_(0),
128 pushed_(pushed), 128 pushed_(pushed),
129 response_received_(false), 129 response_received_(false),
130 session_(session), 130 session_(session),
131 delegate_(NULL), 131 delegate_(NULL),
132 pending_send_flags_(DATA_FLAG_NONE),
132 request_time_(base::Time::Now()), 133 request_time_(base::Time::Now()),
133 response_(new SpdyHeaderBlock), 134 response_(new SpdyHeaderBlock),
134 io_state_(STATE_NONE), 135 io_state_(STATE_NONE),
135 response_status_(OK), 136 response_status_(OK),
136 has_upload_data_(false), 137 has_upload_data_(false),
137 net_log_(net_log), 138 net_log_(net_log),
138 send_bytes_(0), 139 send_bytes_(0),
139 recv_bytes_(0), 140 recv_bytes_(0),
140 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), 141 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE),
141 just_completed_frame_type_(DATA), 142 just_completed_frame_type_(DATA),
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 DCHECK(!has_upload_data_); 619 DCHECK(!has_upload_data_);
619 DCHECK(response_received()); 620 DCHECK(response_received());
620 send_time_ = base::TimeTicks::Now(); 621 send_time_ = base::TimeTicks::Now();
621 return ERR_IO_PENDING; 622 return ERR_IO_PENDING;
622 } 623 }
623 CHECK_EQ(STATE_NONE, io_state_); 624 CHECK_EQ(STATE_NONE, io_state_);
624 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; 625 io_state_ = STATE_GET_DOMAIN_BOUND_CERT;
625 return DoLoop(OK); 626 return DoLoop(OK);
626 } 627 }
627 628
628 void SpdyStream::QueueHeaders(scoped_ptr<SpdyHeaderBlock> headers) { 629 void SpdyStream::SendHeaders(scoped_ptr<SpdyHeaderBlock> headers) {
629 // Until the first headers by SYN_STREAM have been completely sent, we can 630 // Until the first headers by SYN_STREAM have been completely sent, we can
630 // not be sure that our stream_id is correct. 631 // not be sure that our stream_id is correct.
631 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE); 632 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
632 CHECK_GT(stream_id_, 0u); 633 CHECK_GT(stream_id_, 0u);
633 634
634 session_->EnqueueStreamWrite( 635 session_->EnqueueStreamWrite(
635 GetWeakPtr(), HEADERS, 636 GetWeakPtr(), HEADERS,
636 scoped_ptr<SpdyBufferProducer>( 637 scoped_ptr<SpdyBufferProducer>(
637 new HeaderBufferProducer(GetWeakPtr(), headers.Pass()))); 638 new HeaderBufferProducer(GetWeakPtr(), headers.Pass())));
638 } 639 }
639 640
640 void SpdyStream::QueueStreamData(IOBuffer* data, 641 void SpdyStream::SendStreamData(IOBuffer* data,
641 int length, 642 int length,
642 SpdyDataFlags flags) { 643 SpdyDataFlags flags) {
643 // Until the headers have been completely sent, we can not be sure 644 CHECK(!pending_send_data_);
644 // that our stream_id is correct. 645 pending_send_data_ = new DrainableIOBuffer(data, length);
645 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE); 646 pending_send_flags_ = flags;
646 CHECK_GT(stream_id_, 0u); 647 QueueNextDataFrame();
647
648 scoped_ptr<SpdyBuffer> data_buffer(session_->CreateDataBuffer(
649 stream_id_, data, length, flags));
650 // We'll get called again by PossiblyResumeIfSendStalled().
651 if (!data_buffer)
652 return;
653
654 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
655 DCHECK_GE(data_buffer->GetRemainingSize(),
656 session_->GetDataFrameMinimumSize());
657 size_t payload_size =
658 data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize();
659 DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload());
660 DecreaseSendWindowSize(static_cast<int32>(payload_size));
661 // This currently isn't strictly needed, since write frames are
662 // discarded only if the stream is about to be closed. But have it
663 // here anyway just in case this changes.
664 data_buffer->AddConsumeCallback(
665 base::Bind(&SpdyStream::OnWriteBufferConsumed,
666 GetWeakPtr(), payload_size));
667 }
668
669 session_->EnqueueStreamWrite(
670 GetWeakPtr(), DATA,
671 scoped_ptr<SpdyBufferProducer>(
672 new SimpleBufferProducer(data_buffer.Pass())));
673 } 648 }
674 649
675 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, 650 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info,
676 bool* was_npn_negotiated, 651 bool* was_npn_negotiated,
677 NextProto* protocol_negotiated) { 652 NextProto* protocol_negotiated) {
678 return session_->GetSSLInfo( 653 return session_->GetSSLInfo(
679 ssl_info, was_npn_negotiated, protocol_negotiated); 654 ssl_info, was_npn_negotiated, protocol_negotiated);
680 } 655 }
681 656
682 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) { 657 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {
683 return session_->GetSSLCertRequestInfo(cert_request_info); 658 return session_->GetSSLCertRequestInfo(cert_request_info);
684 } 659 }
685 660
686 void SpdyStream::PossiblyResumeIfSendStalled() { 661 void SpdyStream::PossiblyResumeIfSendStalled() {
687 DCHECK(!closed()); 662 DCHECK(!closed());
688 663
689 if (send_stalled_by_flow_control_ && !session_->IsSendStalled() && 664 if (send_stalled_by_flow_control_ && !session_->IsSendStalled() &&
690 send_window_size_ > 0) { 665 send_window_size_ > 0) {
691 net_log_.AddEvent( 666 net_log_.AddEvent(
692 NetLog::TYPE_SPDY_STREAM_FLOW_CONTROL_UNSTALLED, 667 NetLog::TYPE_SPDY_STREAM_FLOW_CONTROL_UNSTALLED,
693 NetLog::IntegerCallback("stream_id", stream_id_)); 668 NetLog::IntegerCallback("stream_id", stream_id_));
694 send_stalled_by_flow_control_ = false; 669 send_stalled_by_flow_control_ = false;
695 io_state_ = STATE_SEND_BODY; 670 QueueNextDataFrame();
696 DoLoop(OK);
697 } 671 }
698 } 672 }
699 673
700 base::WeakPtr<SpdyStream> SpdyStream::GetWeakPtr() { 674 base::WeakPtr<SpdyStream> SpdyStream::GetWeakPtr() {
701 return weak_ptr_factory_.GetWeakPtr(); 675 return weak_ptr_factory_.GetWeakPtr();
702 } 676 }
703 677
704 bool SpdyStream::HasUrl() const { 678 bool SpdyStream::HasUrl() const {
705 if (pushed_) 679 if (pushed_)
706 return response_received(); 680 return response_received();
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 io_state_ = 870 io_state_ =
897 (delegate_->OnSendHeadersComplete() == MORE_DATA_TO_SEND) ? 871 (delegate_->OnSendHeadersComplete() == MORE_DATA_TO_SEND) ?
898 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; 872 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE;
899 873
900 return OK; 874 return OK;
901 } 875 }
902 876
903 // DoSendBody is called to send the optional body for the request. This call 877 // DoSendBody is called to send the optional body for the request. This call
904 // will also be called as each write of a chunk of the body completes. 878 // will also be called as each write of a chunk of the body completes.
905 int SpdyStream::DoSendBody() { 879 int SpdyStream::DoSendBody() {
906 // If we're already in the STATE_SEND_BODY state, then we've already
907 // sent a portion of the body. In that case, we need to first consume
908 // the bytes written in the body stream. Note that the bytes written is
909 // the number of bytes in the frame that were written, only consume the
910 // data portion, of course.
911 io_state_ = STATE_SEND_BODY_COMPLETE; 880 io_state_ = STATE_SEND_BODY_COMPLETE;
912 CHECK(delegate_); 881 CHECK(delegate_);
913 delegate_->OnSendBody(); 882 delegate_->OnSendBody();
914 return ERR_IO_PENDING; 883 return ERR_IO_PENDING;
915 } 884 }
916 885
917 int SpdyStream::DoSendBodyComplete(int result) { 886 int SpdyStream::DoSendBodyComplete(int result) {
918 if (result != OK) 887 if (result != OK)
919 return result; 888 return result;
920 889
921 if (just_completed_frame_type_ != DATA) { 890 if (just_completed_frame_type_ != DATA) {
922 NOTREACHED(); 891 NOTREACHED();
923 return ERR_UNEXPECTED; 892 return ERR_UNEXPECTED;
924 } 893 }
925 894
926 if (just_completed_frame_size_ < session_->GetDataFrameMinimumSize()) { 895 if (just_completed_frame_size_ < session_->GetDataFrameMinimumSize()) {
927 NOTREACHED(); 896 NOTREACHED();
928 return ERR_UNEXPECTED; 897 return ERR_UNEXPECTED;
929 } 898 }
930 899
931 size_t frame_payload_size = 900 size_t frame_payload_size =
932 just_completed_frame_size_ - session_->GetDataFrameMinimumSize(); 901 just_completed_frame_size_ - session_->GetDataFrameMinimumSize();
933 if (frame_payload_size > session_->GetDataFrameMaximumPayload()) { 902 if (frame_payload_size > session_->GetDataFrameMaximumPayload()) {
934 NOTREACHED(); 903 NOTREACHED();
935 return ERR_UNEXPECTED; 904 return ERR_UNEXPECTED;
936 } 905 }
937 906
907 send_bytes_ += frame_payload_size;
908
909 pending_send_data_->DidConsume(frame_payload_size);
910 if (pending_send_data_->BytesRemaining() > 0) {
911 io_state_ = STATE_SEND_BODY_COMPLETE;
912 QueueNextDataFrame();
913 return ERR_IO_PENDING;
914 }
915
916 pending_send_data_ = NULL;
917 pending_send_flags_ = DATA_FLAG_NONE;
918
938 if (!delegate_) { 919 if (!delegate_) {
939 NOTREACHED(); 920 NOTREACHED();
940 return ERR_UNEXPECTED; 921 return ERR_UNEXPECTED;
941 } 922 }
942 923
943 send_bytes_ += frame_payload_size;
944
945 io_state_ = 924 io_state_ =
946 (delegate_->OnSendBodyComplete(frame_payload_size) == MORE_DATA_TO_SEND) ? 925 (delegate_->OnSendBodyComplete() == MORE_DATA_TO_SEND) ?
947 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; 926 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE;
948 927
949 return OK; 928 return OK;
950 } 929 }
951 930
952 int SpdyStream::DoOpen() { 931 int SpdyStream::DoOpen() {
953 io_state_ = STATE_OPEN; 932 io_state_ = STATE_OPEN;
954 933
955 switch (just_completed_frame_type_) { 934 switch (just_completed_frame_type_) {
956 case DATA: { 935 case DATA: {
957 if (just_completed_frame_size_ < session_->GetDataFrameMinimumSize()) { 936 if (just_completed_frame_size_ < session_->GetDataFrameMinimumSize()) {
958 NOTREACHED(); 937 NOTREACHED();
959 return ERR_UNEXPECTED; 938 return ERR_UNEXPECTED;
960 } 939 }
961 940
962 size_t frame_payload_size = 941 size_t frame_payload_size =
963 just_completed_frame_size_ - session_->GetDataFrameMinimumSize(); 942 just_completed_frame_size_ - session_->GetDataFrameMinimumSize();
964 if (frame_payload_size > session_->GetDataFrameMaximumPayload()) { 943 if (frame_payload_size > session_->GetDataFrameMaximumPayload()) {
965 NOTREACHED(); 944 NOTREACHED();
966 return ERR_UNEXPECTED; 945 return ERR_UNEXPECTED;
967 } 946 }
968 947
969 send_bytes_ += frame_payload_size; 948 send_bytes_ += frame_payload_size;
949
950 pending_send_data_->DidConsume(frame_payload_size);
951 if (pending_send_data_->BytesRemaining() > 0) {
952 QueueNextDataFrame();
953 return ERR_IO_PENDING;
954 }
955
956 pending_send_data_ = NULL;
957 pending_send_flags_ = DATA_FLAG_NONE;
Ryan Hamilton 2013/05/23 04:12:00 It's a pity that lines 948-957 are almost complete
akalin 2013/05/23 05:29:38 I did think about this. The problem is, factoring
Ryan Hamilton 2013/05/23 16:26:30 Sounds great. I thought about a helper that retur
958
970 if (delegate_) 959 if (delegate_)
971 delegate_->OnDataSent(frame_payload_size); 960 delegate_->OnDataSent();
961
972 break; 962 break;
973 } 963 }
974 964
975 case HEADERS: 965 case HEADERS:
976 if (delegate_) 966 if (delegate_)
977 delegate_->OnHeadersSent(); 967 delegate_->OnHeadersSent();
978 break; 968 break;
979 969
980 default: 970 default:
981 NOTREACHED(); 971 NOTREACHED();
(...skipping 13 matching lines...) Expand all
995 recv_first_byte_time_ - send_time_); 985 recv_first_byte_time_ - send_time_);
996 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", 986 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime",
997 recv_last_byte_time_ - recv_first_byte_time_); 987 recv_last_byte_time_ - recv_first_byte_time_);
998 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", 988 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime",
999 recv_last_byte_time_ - send_time_); 989 recv_last_byte_time_ - send_time_);
1000 990
1001 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); 991 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_);
1002 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); 992 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_);
1003 } 993 }
1004 994
995 void SpdyStream::QueueNextDataFrame() {
996 // Until the headers have been completely sent, we can not be sure
997 // that our stream_id is correct.
998 DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
999 CHECK_GT(stream_id_, 0u);
1000 CHECK(pending_send_data_);
1001 CHECK_GT(pending_send_data_->BytesRemaining(), 0);
1002
1003 scoped_ptr<SpdyBuffer> data_buffer(session_->CreateDataBuffer(
1004 stream_id_,
1005 pending_send_data_, pending_send_data_->BytesRemaining(),
1006 pending_send_flags_));
1007 // We'll get called again by PossiblyResumeIfSendStalled().
1008 if (!data_buffer)
1009 return;
1010
1011 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
1012 DCHECK_GE(data_buffer->GetRemainingSize(),
1013 session_->GetDataFrameMinimumSize());
1014 size_t payload_size =
1015 data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize();
1016 DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload());
1017 DecreaseSendWindowSize(static_cast<int32>(payload_size));
1018 // This currently isn't strictly needed, since write frames are
1019 // discarded only if the stream is about to be closed. But have it
1020 // here anyway just in case this changes.
1021 data_buffer->AddConsumeCallback(
1022 base::Bind(&SpdyStream::OnWriteBufferConsumed,
1023 GetWeakPtr(), payload_size));
1024 }
1025
1026 session_->EnqueueStreamWrite(
1027 GetWeakPtr(), DATA,
1028 scoped_ptr<SpdyBufferProducer>(
1029 new SimpleBufferProducer(data_buffer.Pass())));
1030 }
1031
1005 } // namespace net 1032 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698