ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / net / quic / quic_flow_controller.cc
blob1fedd06aa813c7dfbf6f711fc0702d91ce6068e7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/quic/quic_flow_controller.h"
7 #include "base/basictypes.h"
8 #include "net/quic/quic_connection.h"
9 #include "net/quic/quic_flags.h"
10 #include "net/quic/quic_protocol.h"
12 namespace net {
14 #define ENDPOINT (is_server_ ? "Server: " : " Client: ")
16 QuicFlowController::QuicFlowController(QuicConnection* connection,
17 QuicStreamId id,
18 bool is_server,
19 QuicStreamOffset send_window_offset,
20 QuicStreamOffset receive_window_offset,
21 QuicByteCount max_receive_window)
22 : connection_(connection),
23 id_(id),
24 is_server_(is_server),
25 bytes_consumed_(0),
26 highest_received_byte_offset_(0),
27 bytes_sent_(0),
28 send_window_offset_(send_window_offset),
29 receive_window_offset_(receive_window_offset),
30 max_receive_window_(max_receive_window),
31 last_blocked_send_window_offset_(0) {
32 DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_
33 << ", setting initial receive window offset to: "
34 << receive_window_offset_
35 << ", max receive window to: "
36 << max_receive_window_
37 << ", setting send window offset to: " << send_window_offset_;
40 void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
41 bytes_consumed_ += bytes_consumed;
42 DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_;
44 MaybeSendWindowUpdate();
47 bool QuicFlowController::UpdateHighestReceivedOffset(
48 QuicStreamOffset new_offset) {
49 // Only update if offset has increased.
50 if (new_offset <= highest_received_byte_offset_) {
51 return false;
54 DVLOG(1) << ENDPOINT << "Stream " << id_
55 << " highest byte offset increased from: "
56 << highest_received_byte_offset_ << " to " << new_offset;
57 highest_received_byte_offset_ = new_offset;
58 return true;
61 void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
62 if (bytes_sent_ + bytes_sent > send_window_offset_) {
63 LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra "
64 << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_
65 << ", and send_window_offset_ = " << send_window_offset_;
66 bytes_sent_ = send_window_offset_;
68 // This is an error on our side, close the connection as soon as possible.
69 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
70 return;
73 bytes_sent_ += bytes_sent;
74 DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_;
77 bool QuicFlowController::FlowControlViolation() {
78 if (highest_received_byte_offset_ > receive_window_offset_) {
79 LOG(ERROR) << ENDPOINT << "Flow control violation on stream "
80 << id_ << ", receive window offset: "
81 << receive_window_offset_
82 << ", highest received byte offset: "
83 << highest_received_byte_offset_;
84 return true;
86 return false;
89 void QuicFlowController::MaybeSendWindowUpdate() {
90 // Send WindowUpdate to increase receive window if
91 // (receive window offset - consumed bytes) < (max window / 2).
92 // This is behaviour copied from SPDY.
93 DCHECK_LT(bytes_consumed_, receive_window_offset_);
94 QuicStreamOffset consumed_window = receive_window_offset_ - bytes_consumed_;
95 QuicByteCount threshold = (max_receive_window_ / 2);
97 if (consumed_window < threshold) {
98 // Update our receive window.
99 receive_window_offset_ += (max_receive_window_ - consumed_window);
101 DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_
102 << ", consumed bytes: " << bytes_consumed_
103 << ", consumed window: " << consumed_window
104 << ", and threshold: " << threshold
105 << ", and max recvw: " << max_receive_window_
106 << ". New receive window offset is: " << receive_window_offset_;
108 // Inform the peer of our new receive window.
109 connection_->SendWindowUpdate(id_, receive_window_offset_);
113 void QuicFlowController::MaybeSendBlocked() {
114 if (SendWindowSize() == 0 &&
115 last_blocked_send_window_offset_ < send_window_offset_) {
116 DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. "
117 << "Send window: " << SendWindowSize()
118 << ", bytes sent: " << bytes_sent_
119 << ", send limit: " << send_window_offset_;
120 // The entire send_window has been consumed, we are now flow control
121 // blocked.
122 connection_->SendBlocked(id_);
124 // Keep track of when we last sent a BLOCKED frame so that we only send one
125 // at a given send offset.
126 last_blocked_send_window_offset_ = send_window_offset_;
130 bool QuicFlowController::UpdateSendWindowOffset(
131 QuicStreamOffset new_send_window_offset) {
132 // Only update if send window has increased.
133 if (new_send_window_offset <= send_window_offset_) {
134 return false;
137 DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_
138 << " with new offset " << new_send_window_offset
139 << " current offset: " << send_window_offset_
140 << " bytes_sent: " << bytes_sent_;
142 const bool blocked = IsBlocked();
143 send_window_offset_ = new_send_window_offset;
144 return blocked;
147 bool QuicFlowController::IsBlocked() const {
148 return SendWindowSize() == 0;
151 uint64 QuicFlowController::SendWindowSize() const {
152 if (bytes_sent_ > send_window_offset_) {
153 return 0;
155 return send_window_offset_ - bytes_sent_;
158 } // namespace net