diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 22:48:48 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 22:48:48 +0000 |
commit | 77b5d50b63b575049688c9ef1edb4b5141f7235d (patch) | |
tree | ff849af6e3d04c94336daed39e83dee93bf76180 /net/quic/reliable_quic_stream.cc | |
parent | 504fca8eaf5f65db2d3766f40be721639a3097f9 (diff) | |
download | chromium_src-77b5d50b63b575049688c9ef1edb4b5141f7235d.zip chromium_src-77b5d50b63b575049688c9ef1edb4b5141f7235d.tar.gz chromium_src-77b5d50b63b575049688c9ef1edb4b5141f7235d.tar.bz2 |
Land Recent QUIC Changes.
Removed QUIC_VERSION_19 from kSupportedQuicVersions. Will
submit a separate CL after making sure all tests pass with
QUIC_VERSION_19.
Introduces QUIC_VERSION_19, connection level flow control.
QuicConnection now has its own flow_controller_ which aggregates bytes
sent/received/consumed from all the streams on a given connection.
WINDOW_UPDATE and BLOCKED frames are sent with a stream_id of 0 when
they refer to the connection.
On receipt of a WINDOW_UPDATE which unblocks the connection level flow
control, all blocked streams are given a chance to write through a call
to OnCanWrite.
QUIC_VERSION_19: connection flow control. Protected behind
--FLAGS_enable_quic_connection_flow_control
Merge internal change: 66020935
https://codereview.chromium.org/265953003/
New QUIC SendAlgorithmInterface which replaces OnPacketAcked,
OnPacketLost, OnPacketAbandoned, and OnRttUpdated with a single
OnCongestionEvent method.
Merge internal change: 66018835
https://codereview.chromium.org/264743011/
Move TransmissionInfo from QuicUnackedPacketMap to QuicProtocol and add
a simple bytes_in_flight accessor.
Merge internal change: 65886839
https://codereview.chromium.org/265993003/
If stream N is added to the write blocked list, and later a
WINDOW_UPDATE frame arrives for the same stream, then stream N will
added for a second time to the write blocked list.
This is wrong - a stream should only be on the write blocked list once.
The write blocked list is implemented as a deque. This CL adds a
parallel set<QuicStreamId> which also keeps track of blocked streams,
but allows more efficient membership testing. This is used to ensure no
duplicate stream IDs end up in the write blocked list.
Don't allow duplicate IDs in QUIC write blocked list.
Merge internal change: 65878293
https://codereview.chromium.org/261983003/
Sync'ing changes with internal source tree. Minor formatting changes.
Merge internal change: 65851919
https://codereview.chromium.org/265813010/
Test-only change to clean up QuicSentPacketManagerTest in order to make
changing the SendAlgorithmInterface easier.
Merge internal change: 65816291
https://codereview.chromium.org/268623010/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/265833015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268980 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/reliable_quic_stream.cc')
-rw-r--r-- | net/quic/reliable_quic_stream.cc | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc index c19dcbf..218bb09 100644 --- a/net/quic/reliable_quic_stream.cc +++ b/net/quic/reliable_quic_stream.cc @@ -131,7 +131,8 @@ ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session) session_->config()->ReceivedInitialFlowControlWindowBytes() : kDefaultFlowControlSendWindow, session_->connection()->max_flow_control_receive_window_bytes(), - session_->connection()->max_flow_control_receive_window_bytes()) { + session_->connection()->max_flow_control_receive_window_bytes()), + connection_flow_controller_(session_->connection()->flow_controller()) { } ReliableQuicStream::~ReliableQuicStream() { @@ -154,7 +155,8 @@ bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { bool accepted = sequencer_.OnStreamFrame(frame); - if (flow_controller_.FlowControlViolation()) { + if (flow_controller_.FlowControlViolation() || + connection_flow_controller_->FlowControlViolation()) { session_->connection()->SendConnectionClose(QUIC_FLOW_CONTROL_ERROR); return false; } @@ -165,6 +167,7 @@ bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { void ReliableQuicStream::MaybeSendWindowUpdate() { flow_controller_.MaybeSendWindowUpdate(session()->connection()); + connection_flow_controller_->MaybeSendWindowUpdate(session()->connection()); } int ReliableQuicStream::num_frames_received() const { @@ -294,6 +297,18 @@ void ReliableQuicStream::OnCanWrite() { } } +void ReliableQuicStream::MaybeSendBlocked() { + flow_controller_.MaybeSendBlocked(session()->connection()); + connection_flow_controller_->MaybeSendBlocked(session()->connection()); + // If we are connection level flow control blocked, then add the stream + // to the write blocked list. It will be given a chance to write when a + // connection level WINDOW_UPDATE arrives. + if (connection_flow_controller_->IsBlocked() && + !flow_controller_.IsBlocked()) { + session_->MarkWriteBlocked(id(), EffectivePriority()); + } +} + QuicConsumedData ReliableQuicStream::WritevData( const struct iovec* iov, int iov_count, @@ -312,11 +327,15 @@ QuicConsumedData ReliableQuicStream::WritevData( if (flow_controller_.IsEnabled()) { // How much data we are allowed to write from flow control. - size_t send_window = flow_controller_.SendWindowSize(); + uint64 send_window = flow_controller_.SendWindowSize(); + if (connection_flow_controller_->IsEnabled()) { + send_window = + min(send_window, connection_flow_controller_->SendWindowSize()); + } if (send_window == 0 && !fin_with_zero_data) { // Quick return if we can't send anything. - flow_controller_.MaybeSendBlocked(session()->connection()); + MaybeSendBlocked(); return QuicConsumedData(0, false); } @@ -337,11 +356,11 @@ QuicConsumedData ReliableQuicStream::WritevData( id(), data, stream_bytes_written_, fin, ack_notifier_delegate); stream_bytes_written_ += consumed_data.bytes_consumed; - flow_controller_.AddBytesSent(consumed_data.bytes_consumed); + AddBytesSent(consumed_data.bytes_consumed); if (consumed_data.bytes_consumed == write_length) { if (!fin_with_zero_data) { - flow_controller_.MaybeSendBlocked(session()->connection()); + MaybeSendBlocked(); } if (fin && consumed_data.fin_consumed) { fin_sent_ = true; @@ -412,8 +431,42 @@ void ReliableQuicStream::OnWindowUpdateFrame( // TODO(rjshade): This does not respect priorities (e.g. multiple // outstanding POSTs are unblocked on arrival of // SHLO with initial window). + // As long as the connection is not flow control blocked, we can write! OnCanWrite(); } } +void ReliableQuicStream::AddBytesBuffered(uint64 bytes) { + if (flow_controller_.IsEnabled()) { + flow_controller_.AddBytesBuffered(bytes); + connection_flow_controller_->AddBytesBuffered(bytes); + } +} + +void ReliableQuicStream::RemoveBytesBuffered(uint64 bytes) { + if (flow_controller_.IsEnabled()) { + flow_controller_.RemoveBytesBuffered(bytes); + connection_flow_controller_->RemoveBytesBuffered(bytes); + } +} + +void ReliableQuicStream::AddBytesSent(uint64 bytes) { + if (flow_controller_.IsEnabled()) { + flow_controller_.AddBytesSent(bytes); + connection_flow_controller_->AddBytesSent(bytes); + } +} + +void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { + if (flow_controller_.IsEnabled()) { + flow_controller_.AddBytesConsumed(bytes); + connection_flow_controller_->AddBytesConsumed(bytes); + } +} + +bool ReliableQuicStream::IsFlowControlBlocked() { + return flow_controller_.IsBlocked() || + connection_flow_controller_->IsBlocked(); +} + } // namespace net |