| 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 "base/profiler/scoped_tracker.h" | 8 #include "base/profiler/scoped_tracker.h" |
| 9 #include "net/quic/iovector.h" | 9 #include "net/quic/iovector.h" |
| 10 #include "net/quic/quic_flow_controller.h" | 10 #include "net/quic/quic_flow_controller.h" |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; | 341 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; |
| 342 return QuicConsumedData(0, false); | 342 return QuicConsumedData(0, false); |
| 343 } | 343 } |
| 344 | 344 |
| 345 // How much data we want to write. | 345 // How much data we want to write. |
| 346 size_t write_length = TotalIovecLength(iov, iov_count); | 346 size_t write_length = TotalIovecLength(iov, iov_count); |
| 347 | 347 |
| 348 // A FIN with zero data payload should not be flow control blocked. | 348 // A FIN with zero data payload should not be flow control blocked. |
| 349 bool fin_with_zero_data = (fin && write_length == 0); | 349 bool fin_with_zero_data = (fin && write_length == 0); |
| 350 | 350 |
| 351 if (flow_controller_.IsEnabled()) { | 351 // How much data we are allowed to write from flow control. |
| 352 // How much data we are allowed to write from flow control. | 352 QuicByteCount send_window = flow_controller_.SendWindowSize(); |
| 353 QuicByteCount send_window = flow_controller_.SendWindowSize(); | 353 if (stream_contributes_to_connection_flow_control_) { |
| 354 if (stream_contributes_to_connection_flow_control_) { | 354 send_window = |
| 355 send_window = | 355 min(send_window, connection_flow_controller_->SendWindowSize()); |
| 356 min(send_window, connection_flow_controller_->SendWindowSize()); | 356 } |
| 357 } | |
| 358 | 357 |
| 359 if (send_window == 0 && !fin_with_zero_data) { | 358 if (send_window == 0 && !fin_with_zero_data) { |
| 360 // Quick return if we can't send anything. | 359 // Quick return if we can't send anything. |
| 361 MaybeSendBlocked(); | 360 MaybeSendBlocked(); |
| 362 return QuicConsumedData(0, false); | 361 return QuicConsumedData(0, false); |
| 363 } | 362 } |
| 364 | 363 |
| 365 if (write_length > send_window) { | 364 if (write_length > send_window) { |
| 366 // Don't send the FIN if we aren't going to send all the data. | 365 // Don't send the FIN if we aren't going to send all the data. |
| 367 fin = false; | 366 fin = false; |
| 368 | 367 |
| 369 // Writing more data would be a violation of flow control. | 368 // Writing more data would be a violation of flow control. |
| 370 write_length = static_cast<size_t>(send_window); | 369 write_length = static_cast<size_t>(send_window); |
| 371 } | |
| 372 } | 370 } |
| 373 | 371 |
| 374 // Fill an IOVector with bytes from the iovec. | 372 // Fill an IOVector with bytes from the iovec. |
| 375 IOVector data; | 373 IOVector data; |
| 376 data.AppendIovecAtMostBytes(iov, iov_count, write_length); | 374 data.AppendIovecAtMostBytes(iov, iov_count, write_length); |
| 377 | 375 |
| 378 QuicConsumedData consumed_data = session()->WritevData( | 376 QuicConsumedData consumed_data = session()->WritevData( |
| 379 id(), data, stream_bytes_written_, fin, GetFecProtection(), | 377 id(), data, stream_bytes_written_, fin, GetFecProtection(), |
| 380 ack_notifier_delegate); | 378 ack_notifier_delegate); |
| 381 stream_bytes_written_ += consumed_data.bytes_consumed; | 379 stream_bytes_written_ += consumed_data.bytes_consumed; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 // endpoints have the same connection level flow control state, mark all | 449 // endpoints have the same connection level flow control state, mark all |
| 452 // unreceived or buffered bytes as consumed. | 450 // unreceived or buffered bytes as consumed. |
| 453 QuicByteCount bytes_to_consume = | 451 QuicByteCount bytes_to_consume = |
| 454 flow_controller_.highest_received_byte_offset() - | 452 flow_controller_.highest_received_byte_offset() - |
| 455 flow_controller_.bytes_consumed(); | 453 flow_controller_.bytes_consumed(); |
| 456 AddBytesConsumed(bytes_to_consume); | 454 AddBytesConsumed(bytes_to_consume); |
| 457 } | 455 } |
| 458 | 456 |
| 459 void ReliableQuicStream::OnWindowUpdateFrame( | 457 void ReliableQuicStream::OnWindowUpdateFrame( |
| 460 const QuicWindowUpdateFrame& frame) { | 458 const QuicWindowUpdateFrame& frame) { |
| 461 if (!flow_controller_.IsEnabled()) { | |
| 462 DLOG(DFATAL) << "Flow control not enabled! " << version(); | |
| 463 return; | |
| 464 } | |
| 465 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { | 459 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { |
| 466 // We can write again! | 460 // We can write again! |
| 467 // TODO(rjshade): This does not respect priorities (e.g. multiple | 461 // TODO(rjshade): This does not respect priorities (e.g. multiple |
| 468 // outstanding POSTs are unblocked on arrival of | 462 // outstanding POSTs are unblocked on arrival of |
| 469 // SHLO with initial window). | 463 // SHLO with initial window). |
| 470 // As long as the connection is not flow control blocked, we can write! | 464 // As long as the connection is not flow control blocked, we can write! |
| 471 OnCanWrite(); | 465 OnCanWrite(); |
| 472 } | 466 } |
| 473 } | 467 } |
| 474 | 468 |
| 475 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset( | 469 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset( |
| 476 QuicStreamOffset new_offset) { | 470 QuicStreamOffset new_offset) { |
| 477 if (!flow_controller_.IsEnabled()) { | |
| 478 return false; | |
| 479 } | |
| 480 uint64 increment = | 471 uint64 increment = |
| 481 new_offset - flow_controller_.highest_received_byte_offset(); | 472 new_offset - flow_controller_.highest_received_byte_offset(); |
| 482 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { | 473 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { |
| 483 return false; | 474 return false; |
| 484 } | 475 } |
| 485 | 476 |
| 486 // If |new_offset| increased the stream flow controller's highest received | 477 // If |new_offset| increased the stream flow controller's highest received |
| 487 // offset, then we need to increase the connection flow controller's value | 478 // offset, then we need to increase the connection flow controller's value |
| 488 // by the incremental difference. | 479 // by the incremental difference. |
| 489 if (stream_contributes_to_connection_flow_control_) { | 480 if (stream_contributes_to_connection_flow_control_) { |
| 490 connection_flow_controller_->UpdateHighestReceivedOffset( | 481 connection_flow_controller_->UpdateHighestReceivedOffset( |
| 491 connection_flow_controller_->highest_received_byte_offset() + | 482 connection_flow_controller_->highest_received_byte_offset() + |
| 492 increment); | 483 increment); |
| 493 } | 484 } |
| 494 return true; | 485 return true; |
| 495 } | 486 } |
| 496 | 487 |
| 497 void ReliableQuicStream::AddBytesSent(QuicByteCount bytes) { | 488 void ReliableQuicStream::AddBytesSent(QuicByteCount bytes) { |
| 498 if (flow_controller_.IsEnabled()) { | 489 flow_controller_.AddBytesSent(bytes); |
| 499 flow_controller_.AddBytesSent(bytes); | 490 if (stream_contributes_to_connection_flow_control_) { |
| 500 if (stream_contributes_to_connection_flow_control_) { | 491 connection_flow_controller_->AddBytesSent(bytes); |
| 501 connection_flow_controller_->AddBytesSent(bytes); | |
| 502 } | |
| 503 } | 492 } |
| 504 } | 493 } |
| 505 | 494 |
| 506 void ReliableQuicStream::AddBytesConsumed(QuicByteCount bytes) { | 495 void ReliableQuicStream::AddBytesConsumed(QuicByteCount bytes) { |
| 507 if (flow_controller_.IsEnabled()) { | 496 // Only adjust stream level flow controller if we are still reading. |
| 508 // Only adjust stream level flow controller if we are still reading. | 497 if (!read_side_closed_) { |
| 509 if (!read_side_closed_) { | 498 flow_controller_.AddBytesConsumed(bytes); |
| 510 flow_controller_.AddBytesConsumed(bytes); | 499 } |
| 511 } | |
| 512 | 500 |
| 513 if (stream_contributes_to_connection_flow_control_) { | 501 if (stream_contributes_to_connection_flow_control_) { |
| 514 connection_flow_controller_->AddBytesConsumed(bytes); | 502 connection_flow_controller_->AddBytesConsumed(bytes); |
| 515 } | |
| 516 } | 503 } |
| 517 } | 504 } |
| 518 | 505 |
| 519 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { | 506 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { |
| 520 if (flow_controller_.UpdateSendWindowOffset(new_window)) { | 507 if (flow_controller_.UpdateSendWindowOffset(new_window)) { |
| 521 OnCanWrite(); | 508 OnCanWrite(); |
| 522 } | 509 } |
| 523 } | 510 } |
| 524 | 511 |
| 525 bool ReliableQuicStream::IsFlowControlBlocked() { | 512 bool ReliableQuicStream::IsFlowControlBlocked() { |
| 526 if (flow_controller_.IsBlocked()) { | 513 if (flow_controller_.IsBlocked()) { |
| 527 return true; | 514 return true; |
| 528 } | 515 } |
| 529 return stream_contributes_to_connection_flow_control_ && | 516 return stream_contributes_to_connection_flow_control_ && |
| 530 connection_flow_controller_->IsBlocked(); | 517 connection_flow_controller_->IsBlocked(); |
| 531 } | 518 } |
| 532 | 519 |
| 533 } // namespace net | 520 } // namespace net |
| OLD | NEW |