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

Unified Diff: net/quic/quic_flow_controller.cc

Issue 242593002: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Build fix. Use uint32 instead of int Created 6 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
« no previous file with comments | « net/quic/quic_flow_controller.h ('k') | net/quic/quic_flow_controller_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_flow_controller.cc
diff --git a/net/quic/quic_flow_controller.cc b/net/quic/quic_flow_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b9a9e448546bc7db7cbfdce54adb33d1d6f64a01
--- /dev/null
+++ b/net/quic/quic_flow_controller.cc
@@ -0,0 +1,183 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_flow_controller.h"
+
+#include "base/basictypes.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_protocol.h"
+
+namespace net {
+
+#define ENDPOINT (is_server_ ? "Server: " : " Client: ")
+
+QuicFlowController::QuicFlowController(QuicStreamId id,
+ bool is_server,
+ uint64 send_window_offset,
+ uint64 receive_window_offset,
+ uint64 max_receive_window)
+ : id_(id),
+ is_enabled_(true),
+ is_server_(is_server),
+ bytes_consumed_(0),
+ bytes_buffered_(0),
+ bytes_sent_(0),
+ send_window_offset_(send_window_offset),
+ receive_window_offset_(receive_window_offset),
+ max_receive_window_(max_receive_window) {
+ DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_
+ << ", setting initial receive window offset to: "
+ << receive_window_offset_
+ << ", max receive window to: "
+ << max_receive_window_
+ << ", setting send window offset to: " << send_window_offset_;
+}
+
+void QuicFlowController::AddBytesConsumed(uint64 bytes_consumed) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ bytes_consumed_ += bytes_consumed;
+ DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_;
+}
+
+void QuicFlowController::AddBytesBuffered(uint64 bytes_buffered) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ bytes_buffered_ += bytes_buffered;
+ DVLOG(1) << ENDPOINT << "Stream " << id_ << " buffered: " << bytes_buffered_;
+}
+
+void QuicFlowController::RemoveBytesBuffered(uint64 bytes_buffered) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ if (bytes_buffered_ < bytes_buffered) {
+ LOG(DFATAL) << "Trying to remove " << bytes_buffered << " bytes, when only "
+ << bytes_buffered_ << " bytes are buffered";
+ bytes_buffered_ = 0;
+ return;
+ }
+
+ bytes_buffered_ -= bytes_buffered;
+ DVLOG(1) << ENDPOINT << "Stream " << id_ << " buffered: " << bytes_buffered_;
+}
+
+void QuicFlowController::AddBytesSent(uint64 bytes_sent) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ if (bytes_sent_ + bytes_sent > send_window_offset_) {
+ LOG(DFATAL) << "Trying to send an extra " << bytes_sent
+ << " bytes, when bytes_sent = " << bytes_sent_
+ << ", and send_window = " << send_window_offset_;
+ bytes_sent_ = send_window_offset_;
+ return;
+ }
+
+ bytes_sent_ += bytes_sent;
+ DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_;
+}
+
+bool QuicFlowController::FlowControlViolation() {
+ if (receive_window_offset_ < TotalReceivedBytes()) {
+ // TODO(rjshade): Lower severity from DFATAL once we have established that
+ // flow control is working correctly.
+ LOG(DFATAL)
+ << ENDPOINT << "Flow control violation on stream " << id_
+ << ", receive window: " << receive_window_offset_
+ << ", bytes received: " << TotalReceivedBytes();
+
+ return true;
+ }
+ return false;
+}
+
+void QuicFlowController::MaybeSendWindowUpdate(QuicConnection* connection) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ // Send WindowUpdate to increase receive window if
+ // (receive window offset - consumed bytes) < (max window / 2).
+ // This is behaviour copied from SPDY.
+ size_t consumed_window = receive_window_offset_ - bytes_consumed_;
+ size_t threshold = (max_receive_window_ / 2);
+
+ if (consumed_window < threshold) {
+ // Update our receive window.
+ receive_window_offset_ += (max_receive_window_ - consumed_window);
+
+ DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_
+ << ", consumed bytes: " << bytes_consumed_
+ << ", consumed window: " << consumed_window
+ << ", and threshold: " << threshold
+ << ", and max recvw: " << max_receive_window_
+ << ". New receive window offset is: " << receive_window_offset_;
+
+ // Inform the peer of our new receive window.
+ connection->SendWindowUpdate(id_, receive_window_offset_);
+ }
+}
+
+void QuicFlowController::MaybeSendBlocked(QuicConnection* connection) {
+ if (!IsEnabled()) {
+ return;
+ }
+
+ if (SendWindowSize() == 0) {
+ DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. "
+ << "Send window: " << SendWindowSize()
+ << ", bytes sent: " << bytes_sent_
+ << ", send limit: " << send_window_offset_;
+ // The entire send_window has been consumed, we are now flow control
+ // blocked.
+ connection->SendBlocked(id_);
+ }
+}
+
+bool QuicFlowController::UpdateSendWindowOffset(uint64 new_send_window_offset) {
+ // Only update if send window has increased.
+ if (new_send_window_offset <= send_window_offset_) {
+ return false;
+ }
+
+ DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_
+ << " with new offset " << new_send_window_offset
+ << " , current offset: " << send_window_offset_;
+
+ send_window_offset_ = new_send_window_offset;
+ return true;
+}
+
+void QuicFlowController::Disable() {
+ is_enabled_ = false;
+}
+
+bool QuicFlowController::IsEnabled() const {
+ return FLAGS_enable_quic_stream_flow_control && is_enabled_;
+}
+
+bool QuicFlowController::IsBlocked() const {
+ return IsEnabled() && SendWindowSize() == 0;
+}
+
+uint64 QuicFlowController::SendWindowSize() const {
+ if (bytes_sent_ > send_window_offset_) {
+ return 0;
+ }
+ return send_window_offset_ - bytes_sent_;
+}
+
+uint64 QuicFlowController::TotalReceivedBytes() const {
+ return bytes_consumed_ + bytes_buffered_;
+}
+
+} // namespace net
« no previous file with comments | « net/quic/quic_flow_controller.h ('k') | net/quic/quic_flow_controller_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698