OLD | NEW |
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/quic/reliable_quic_stream.h" | 5 #include "net/quic/reliable_quic_stream.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "net/quic/iovector.h" | 8 #include "net/quic/iovector.h" |
9 #include "net/quic/quic_flow_controller.h" | 9 #include "net/quic/quic_flow_controller.h" |
10 #include "net/quic/quic_session.h" | 10 #include "net/quic/quic_session.h" |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 fin_received_(false), | 152 fin_received_(false), |
153 rst_sent_(false), | 153 rst_sent_(false), |
154 rst_received_(false), | 154 rst_received_(false), |
155 fec_policy_(FEC_PROTECT_OPTIONAL), | 155 fec_policy_(FEC_PROTECT_OPTIONAL), |
156 is_server_(session_->is_server()), | 156 is_server_(session_->is_server()), |
157 flow_controller_( | 157 flow_controller_( |
158 session_->connection(), id_, is_server_, | 158 session_->connection(), id_, is_server_, |
159 GetReceivedFlowControlWindow(session), | 159 GetReceivedFlowControlWindow(session), |
160 GetInitialStreamFlowControlWindowToSend(session), | 160 GetInitialStreamFlowControlWindowToSend(session), |
161 GetInitialStreamFlowControlWindowToSend(session)), | 161 GetInitialStreamFlowControlWindowToSend(session)), |
162 connection_flow_controller_(session_->flow_controller()) { | 162 connection_flow_controller_(session_->flow_controller()), |
| 163 stream_contributes_to_connection_flow_control_(true) { |
163 } | 164 } |
164 | 165 |
165 ReliableQuicStream::~ReliableQuicStream() { | 166 ReliableQuicStream::~ReliableQuicStream() { |
166 } | 167 } |
167 | 168 |
168 bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { | 169 bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { |
169 if (read_side_closed_) { | 170 if (read_side_closed_) { |
170 DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; | 171 DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; |
171 // We don't want to be reading: blackhole the data. | 172 // We don't want to be reading: blackhole the data. |
172 return true; | 173 return true; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 delegate->WroteData(false); | 326 delegate->WroteData(false); |
326 } | 327 } |
327 } | 328 } |
328 break; | 329 break; |
329 } | 330 } |
330 } | 331 } |
331 } | 332 } |
332 | 333 |
333 void ReliableQuicStream::MaybeSendBlocked() { | 334 void ReliableQuicStream::MaybeSendBlocked() { |
334 flow_controller_.MaybeSendBlocked(); | 335 flow_controller_.MaybeSendBlocked(); |
335 connection_flow_controller_->MaybeSendBlocked(); | 336 if (stream_contributes_to_connection_flow_control_) { |
| 337 connection_flow_controller_->MaybeSendBlocked(); |
| 338 } |
336 // If we are connection level flow control blocked, then add the stream | 339 // If we are connection level flow control blocked, then add the stream |
337 // to the write blocked list. It will be given a chance to write when a | 340 // to the write blocked list. It will be given a chance to write when a |
338 // connection level WINDOW_UPDATE arrives. | 341 // connection level WINDOW_UPDATE arrives. |
339 if (connection_flow_controller_->IsBlocked() && | 342 if (stream_contributes_to_connection_flow_control_ && |
| 343 connection_flow_controller_->IsBlocked() && |
340 !flow_controller_.IsBlocked()) { | 344 !flow_controller_.IsBlocked()) { |
341 session_->MarkWriteBlocked(id(), EffectivePriority()); | 345 session_->MarkWriteBlocked(id(), EffectivePriority()); |
342 } | 346 } |
343 } | 347 } |
344 | 348 |
345 QuicConsumedData ReliableQuicStream::WritevData( | 349 QuicConsumedData ReliableQuicStream::WritevData( |
346 const struct iovec* iov, | 350 const struct iovec* iov, |
347 int iov_count, | 351 int iov_count, |
348 bool fin, | 352 bool fin, |
349 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { | 353 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { |
350 if (write_side_closed_) { | 354 if (write_side_closed_) { |
351 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; | 355 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; |
352 return QuicConsumedData(0, false); | 356 return QuicConsumedData(0, false); |
353 } | 357 } |
354 | 358 |
355 // How much data we want to write. | 359 // How much data we want to write. |
356 size_t write_length = TotalIovecLength(iov, iov_count); | 360 size_t write_length = TotalIovecLength(iov, iov_count); |
357 | 361 |
358 // A FIN with zero data payload should not be flow control blocked. | 362 // A FIN with zero data payload should not be flow control blocked. |
359 bool fin_with_zero_data = (fin && write_length == 0); | 363 bool fin_with_zero_data = (fin && write_length == 0); |
360 | 364 |
361 if (flow_controller_.IsEnabled()) { | 365 if (flow_controller_.IsEnabled()) { |
362 // How much data we are allowed to write from flow control. | 366 // How much data we are allowed to write from flow control. |
363 uint64 send_window = flow_controller_.SendWindowSize(); | 367 uint64 send_window = flow_controller_.SendWindowSize(); |
364 if (connection_flow_controller_->IsEnabled()) { | 368 // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when |
| 369 // removing QUIC_VERSION_19. |
| 370 if (stream_contributes_to_connection_flow_control_ && |
| 371 connection_flow_controller_->IsEnabled()) { |
365 send_window = | 372 send_window = |
366 min(send_window, connection_flow_controller_->SendWindowSize()); | 373 min(send_window, connection_flow_controller_->SendWindowSize()); |
367 } | 374 } |
368 | 375 |
369 if (send_window == 0 && !fin_with_zero_data) { | 376 if (send_window == 0 && !fin_with_zero_data) { |
370 // Quick return if we can't send anything. | 377 // Quick return if we can't send anything. |
371 MaybeSendBlocked(); | 378 MaybeSendBlocked(); |
372 return QuicConsumedData(0, false); | 379 return QuicConsumedData(0, false); |
373 } | 380 } |
374 | 381 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 490 } |
484 | 491 |
485 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) { | 492 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) { |
486 if (flow_controller_.IsEnabled()) { | 493 if (flow_controller_.IsEnabled()) { |
487 uint64 increment = | 494 uint64 increment = |
488 new_offset - flow_controller_.highest_received_byte_offset(); | 495 new_offset - flow_controller_.highest_received_byte_offset(); |
489 if (flow_controller_.UpdateHighestReceivedOffset(new_offset)) { | 496 if (flow_controller_.UpdateHighestReceivedOffset(new_offset)) { |
490 // If |new_offset| increased the stream flow controller's highest received | 497 // If |new_offset| increased the stream flow controller's highest received |
491 // offset, then we need to increase the connection flow controller's value | 498 // offset, then we need to increase the connection flow controller's value |
492 // by the incremental difference. | 499 // by the incremental difference. |
493 connection_flow_controller_->UpdateHighestReceivedOffset( | 500 if (stream_contributes_to_connection_flow_control_) { |
494 connection_flow_controller_->highest_received_byte_offset() + | 501 connection_flow_controller_->UpdateHighestReceivedOffset( |
495 increment); | 502 connection_flow_controller_->highest_received_byte_offset() + |
| 503 increment); |
| 504 } |
496 return true; | 505 return true; |
497 } | 506 } |
498 } | 507 } |
499 return false; | 508 return false; |
500 } | 509 } |
501 | 510 |
502 void ReliableQuicStream::AddBytesSent(uint64 bytes) { | 511 void ReliableQuicStream::AddBytesSent(uint64 bytes) { |
503 if (flow_controller_.IsEnabled()) { | 512 if (flow_controller_.IsEnabled()) { |
504 flow_controller_.AddBytesSent(bytes); | 513 flow_controller_.AddBytesSent(bytes); |
505 connection_flow_controller_->AddBytesSent(bytes); | 514 if (stream_contributes_to_connection_flow_control_) { |
| 515 connection_flow_controller_->AddBytesSent(bytes); |
| 516 } |
506 } | 517 } |
507 } | 518 } |
508 | 519 |
509 void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { | 520 void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { |
510 if (flow_controller_.IsEnabled()) { | 521 if (flow_controller_.IsEnabled()) { |
511 // Only adjust stream level flow controller if we are still reading. | 522 // Only adjust stream level flow controller if we are still reading. |
512 if (!read_side_closed_) { | 523 if (!read_side_closed_) { |
513 flow_controller_.AddBytesConsumed(bytes); | 524 flow_controller_.AddBytesConsumed(bytes); |
514 } | 525 } |
515 | 526 |
516 connection_flow_controller_->AddBytesConsumed(bytes); | 527 if (stream_contributes_to_connection_flow_control_) { |
| 528 connection_flow_controller_->AddBytesConsumed(bytes); |
| 529 } |
517 } | 530 } |
518 } | 531 } |
519 | 532 |
520 bool ReliableQuicStream::IsFlowControlBlocked() { | 533 bool ReliableQuicStream::IsFlowControlBlocked() { |
521 return flow_controller_.IsBlocked() || | 534 bool stream_flow_control_blocked = flow_controller_.IsBlocked(); |
522 connection_flow_controller_->IsBlocked(); | 535 bool connecton_flow_control_blocked = |
| 536 stream_contributes_to_connection_flow_control_ && |
| 537 connection_flow_controller_->IsBlocked(); |
| 538 return stream_flow_control_blocked || connecton_flow_control_blocked; |
523 } | 539 } |
524 | 540 |
525 } // namespace net | 541 } // namespace net |
OLD | NEW |