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

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

Issue 13872016: [SPDY] Add histograms for flow control stalls (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // Find our stream. 746 // Find our stream.
747 CHECK(IsStreamActive(stream_id)); 747 CHECK(IsStreamActive(stream_id));
748 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 748 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
749 CHECK_EQ(stream->stream_id(), stream_id); 749 CHECK_EQ(stream->stream_id(), stream_id);
750 750
751 if (len < 0) { 751 if (len < 0) {
752 NOTREACHED(); 752 NOTREACHED();
753 return scoped_ptr<SpdyBuffer>(); 753 return scoped_ptr<SpdyBuffer>();
754 } 754 }
755 755
756 if (len > kMaxSpdyFrameChunkSize) { 756 int effective_len = std::min(len, kMaxSpdyFrameChunkSize);
757 len = kMaxSpdyFrameChunkSize; 757
758 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 758 bool send_stalled_by_stream = false;
759 if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
760 send_stalled_by_stream = (stream->send_window_size() <= 0);
761 UMA_HISTOGRAM_BOOLEAN("Net.SpdyDataFrameSendStalledByStream",
762 send_stalled_by_stream);
759 } 763 }
760 764
761 // Obey send window size of the stream (and session, if applicable) 765 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
762 // if flow control is enabled. 766 UMA_HISTOGRAM_BOOLEAN("Net.SpdyDataFrameSendStalledBySession",
767 IsSendStalled());
768 }
769
770 // Obey send window size of the stream if stream flow control is
771 // enabled.
763 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { 772 if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
764 int32 effective_window_size = stream->send_window_size(); 773 if (send_stalled_by_stream) {
765 if (effective_window_size <= 0) {
766 // Because we queue frames onto the session, it is possible that
767 // a stream was not flow controlled at the time it attempted the
768 // write, but when we go to fulfill the write, it is now flow
769 // controlled. This is why we need the session to mark the stream
770 // as stalled - because only the session knows for sure when the
771 // stall occurs.
772 stream->set_send_stalled_by_flow_control(true); 774 stream->set_send_stalled_by_flow_control(true);
773 net_log().AddEvent( 775 net_log().AddEvent(
774 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_STREAM_SEND_WINDOW, 776 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
775 NetLog::IntegerCallback("stream_id", stream_id)); 777 NetLog::IntegerCallback("stream_id", stream_id));
776 return scoped_ptr<SpdyBuffer>(); 778 return scoped_ptr<SpdyBuffer>();
777 } 779 }
778 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 780
779 effective_window_size = 781 effective_len = std::min(effective_len, stream->send_window_size());
780 std::min(effective_window_size, session_send_window_size_); 782 }
781 if (effective_window_size <= 0) { 783
782 DCHECK(IsSendStalled()); 784 // Obey send window size of the session if session flow control is
783 stream->set_send_stalled_by_flow_control(true); 785 // enabled.
784 QueueSendStalledStream(stream); 786 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
785 net_log().AddEvent( 787 if (IsSendStalled()) {
786 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_SESSION_SEND_WINDOW, 788 stream->set_send_stalled_by_flow_control(true);
787 NetLog::IntegerCallback("stream_id", stream_id)); 789 QueueSendStalledStream(stream);
788 return scoped_ptr<SpdyBuffer>(); 790 net_log().AddEvent(
789 } 791 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
792 NetLog::IntegerCallback("stream_id", stream_id));
793 return scoped_ptr<SpdyBuffer>();
790 } 794 }
791 795
792 int new_len = std::min(len, effective_window_size); 796 effective_len = std::min(effective_len, session_send_window_size_);
793 if (new_len < len) {
794 len = new_len;
795 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
796 }
797 } 797 }
798 798
799 DCHECK_GE(effective_len, 0);
800
801 // Clear FIN flag if only some of the data will be in the data
802 // frame.
803 if (effective_len < len)
804 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
805
799 if (net_log().IsLoggingAllEvents()) { 806 if (net_log().IsLoggingAllEvents()) {
800 net_log().AddEvent( 807 net_log().AddEvent(
801 NetLog::TYPE_SPDY_SESSION_SEND_DATA, 808 NetLog::TYPE_SPDY_SESSION_SEND_DATA,
802 base::Bind(&NetLogSpdyDataCallback, stream_id, len, 809 base::Bind(&NetLogSpdyDataCallback, stream_id, effective_len,
803 (flags & DATA_FLAG_FIN) != 0)); 810 (flags & DATA_FLAG_FIN) != 0));
804 } 811 }
805 812
806 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. 813 // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
807 if (len > 0) 814 if (effective_len > 0)
808 SendPrefacePingIfNoneInFlight(); 815 SendPrefacePingIfNoneInFlight();
809 816
810 // TODO(mbelshe): reduce memory copies here. 817 // TODO(mbelshe): reduce memory copies here.
811 DCHECK(buffered_spdy_framer_.get()); 818 DCHECK(buffered_spdy_framer_.get());
812 scoped_ptr<SpdyFrame> frame( 819 scoped_ptr<SpdyFrame> frame(
813 buffered_spdy_framer_->CreateDataFrame( 820 buffered_spdy_framer_->CreateDataFrame(
814 stream_id, data->data(), static_cast<uint32>(len), flags)); 821 stream_id, data->data(),
822 static_cast<uint32>(effective_len), flags));
815 823
816 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass())); 824 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass()));
817 825
818 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 826 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
819 DecreaseSendWindowSize(static_cast<int32>(len)); 827 DecreaseSendWindowSize(static_cast<int32>(effective_len));
820 data_buffer->AddConsumeCallback( 828 data_buffer->AddConsumeCallback(
821 base::Bind(&SpdySession::OnWriteBufferConsumed, 829 base::Bind(&SpdySession::OnWriteBufferConsumed,
822 weak_factory_.GetWeakPtr(), 830 weak_factory_.GetWeakPtr(),
823 static_cast<size_t>(len))); 831 static_cast<size_t>(effective_len)));
824 } 832 }
825 833
826 return data_buffer.Pass(); 834 return data_buffer.Pass();
827 } 835 }
828 836
829 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { 837 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) {
830 DCHECK_NE(0u, stream_id); 838 DCHECK_NE(0u, stream_id);
831 // TODO(mbelshe): We should send a RST_STREAM control frame here 839 // TODO(mbelshe): We should send a RST_STREAM control frame here
832 // so that the server can cancel a large send. 840 // so that the server can cancel a large send.
833 841
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 if (!queue->empty()) { 2375 if (!queue->empty()) {
2368 SpdyStreamId stream_id = queue->front(); 2376 SpdyStreamId stream_id = queue->front();
2369 queue->pop_front(); 2377 queue->pop_front();
2370 return stream_id; 2378 return stream_id;
2371 } 2379 }
2372 } 2380 }
2373 return 0; 2381 return 0;
2374 } 2382 }
2375 2383
2376 } // namespace net 2384 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698