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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: net/spdy/spdy_session.cc
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 760e4e330054888836fe3fc06ceef94e462e7c41..343cf9fa84b1ab23d41ee77df332cde93e6878ad 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -753,74 +753,82 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
return scoped_ptr<SpdyBuffer>();
}
- if (len > kMaxSpdyFrameChunkSize) {
- len = kMaxSpdyFrameChunkSize;
- flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
+ int effective_len = std::min(len, kMaxSpdyFrameChunkSize);
+
+ bool send_stalled_by_stream = false;
+ if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
+ send_stalled_by_stream = (stream->send_window_size() <= 0);
+ UMA_HISTOGRAM_BOOLEAN("Net.SpdyDataFrameSendStalledByStream",
+ send_stalled_by_stream);
+ }
+
+ if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
+ UMA_HISTOGRAM_BOOLEAN("Net.SpdyDataFrameSendStalledBySession",
+ IsSendStalled());
}
- // Obey send window size of the stream (and session, if applicable)
- // if flow control is enabled.
+ // Obey send window size of the stream if stream flow control is
+ // enabled.
if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
- int32 effective_window_size = stream->send_window_size();
- if (effective_window_size <= 0) {
- // Because we queue frames onto the session, it is possible that
- // a stream was not flow controlled at the time it attempted the
- // write, but when we go to fulfill the write, it is now flow
- // controlled. This is why we need the session to mark the stream
- // as stalled - because only the session knows for sure when the
- // stall occurs.
+ if (send_stalled_by_stream) {
stream->set_send_stalled_by_flow_control(true);
net_log().AddEvent(
- NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_STREAM_SEND_WINDOW,
+ NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
NetLog::IntegerCallback("stream_id", stream_id));
return scoped_ptr<SpdyBuffer>();
}
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- effective_window_size =
- std::min(effective_window_size, session_send_window_size_);
- if (effective_window_size <= 0) {
- DCHECK(IsSendStalled());
- stream->set_send_stalled_by_flow_control(true);
- QueueSendStalledStream(stream);
- net_log().AddEvent(
- NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_SESSION_SEND_WINDOW,
- NetLog::IntegerCallback("stream_id", stream_id));
- return scoped_ptr<SpdyBuffer>();
- }
- }
- int new_len = std::min(len, effective_window_size);
- if (new_len < len) {
- len = new_len;
- flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
+ effective_len = std::min(effective_len, stream->send_window_size());
+ }
+
+ // Obey send window size of the session if session flow control is
+ // enabled.
+ if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
+ if (IsSendStalled()) {
+ stream->set_send_stalled_by_flow_control(true);
+ QueueSendStalledStream(stream);
+ net_log().AddEvent(
+ NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
+ NetLog::IntegerCallback("stream_id", stream_id));
+ return scoped_ptr<SpdyBuffer>();
}
+
+ effective_len = std::min(effective_len, session_send_window_size_);
}
+ DCHECK_GE(effective_len, 0);
+
+ // Clear FIN flag if only some of the data will be in the data
+ // frame.
+ if (effective_len < len)
+ flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
+
if (net_log().IsLoggingAllEvents()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_SEND_DATA,
- base::Bind(&NetLogSpdyDataCallback, stream_id, len,
+ base::Bind(&NetLogSpdyDataCallback, stream_id, effective_len,
(flags & DATA_FLAG_FIN) != 0));
}
// Send PrefacePing for DATA_FRAMEs with nonzero payload size.
- if (len > 0)
+ if (effective_len > 0)
SendPrefacePingIfNoneInFlight();
// TODO(mbelshe): reduce memory copies here.
DCHECK(buffered_spdy_framer_.get());
scoped_ptr<SpdyFrame> frame(
buffered_spdy_framer_->CreateDataFrame(
- stream_id, data->data(), static_cast<uint32>(len), flags));
+ stream_id, data->data(),
+ static_cast<uint32>(effective_len), flags));
scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass()));
if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- DecreaseSendWindowSize(static_cast<int32>(len));
+ DecreaseSendWindowSize(static_cast<int32>(effective_len));
data_buffer->AddConsumeCallback(
base::Bind(&SpdySession::OnWriteBufferConsumed,
weak_factory_.GetWeakPtr(),
- static_cast<size_t>(len)));
+ static_cast<size_t>(effective_len)));
}
return data_buffer.Pass();

Powered by Google App Engine
This is Rietveld 408576698