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 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 356 } |
357 | 357 |
358 // How much data we want to write. | 358 // How much data we want to write. |
359 size_t write_length = TotalIovecLength(iov, iov_count); | 359 size_t write_length = TotalIovecLength(iov, iov_count); |
360 | 360 |
361 // A FIN with zero data payload should not be flow control blocked. | 361 // A FIN with zero data payload should not be flow control blocked. |
362 bool fin_with_zero_data = (fin && write_length == 0); | 362 bool fin_with_zero_data = (fin && write_length == 0); |
363 | 363 |
364 if (flow_controller_.IsEnabled()) { | 364 if (flow_controller_.IsEnabled()) { |
365 // How much data we are allowed to write from flow control. | 365 // How much data we are allowed to write from flow control. |
366 uint64 send_window = flow_controller_.SendWindowSize(); | 366 QuicByteCount send_window = flow_controller_.SendWindowSize(); |
367 // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when | 367 // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when |
368 // removing QUIC_VERSION_19. | 368 // removing QUIC_VERSION_19. |
369 if (stream_contributes_to_connection_flow_control_ && | 369 if (stream_contributes_to_connection_flow_control_ && |
370 connection_flow_controller_->IsEnabled()) { | 370 connection_flow_controller_->IsEnabled()) { |
371 send_window = | 371 send_window = |
372 min(send_window, connection_flow_controller_->SendWindowSize()); | 372 min(send_window, connection_flow_controller_->SendWindowSize()); |
373 } | 373 } |
374 | 374 |
375 if (send_window == 0 && !fin_with_zero_data) { | 375 if (send_window == 0 && !fin_with_zero_data) { |
376 // Quick return if we can't send anything. | 376 // Quick return if we can't send anything. |
377 MaybeSendBlocked(); | 377 MaybeSendBlocked(); |
378 return QuicConsumedData(0, false); | 378 return QuicConsumedData(0, false); |
379 } | 379 } |
380 | 380 |
381 if (write_length > send_window) { | 381 if (write_length > send_window) { |
382 // Don't send the FIN if we aren't going to send all the data. | 382 // Don't send the FIN if we aren't going to send all the data. |
383 fin = false; | 383 fin = false; |
384 | 384 |
385 // Writing more data would be a violation of flow control. | 385 // Writing more data would be a violation of flow control. |
386 write_length = send_window; | 386 write_length = static_cast<size_t>(send_window); |
387 } | 387 } |
388 } | 388 } |
389 | 389 |
390 // Fill an IOVector with bytes from the iovec. | 390 // Fill an IOVector with bytes from the iovec. |
391 IOVector data; | 391 IOVector data; |
392 data.AppendIovecAtMostBytes(iov, iov_count, write_length); | 392 data.AppendIovecAtMostBytes(iov, iov_count, write_length); |
393 | 393 |
394 QuicConsumedData consumed_data = session()->WritevData( | 394 QuicConsumedData consumed_data = session()->WritevData( |
395 id(), data, stream_bytes_written_, fin, GetFecProtection(), | 395 id(), data, stream_bytes_written_, fin, GetFecProtection(), |
396 ack_notifier_delegate); | 396 ack_notifier_delegate); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); | 459 DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); |
460 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, | 460 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, |
461 stream_bytes_written_); | 461 stream_bytes_written_); |
462 rst_sent_ = true; | 462 rst_sent_ = true; |
463 } | 463 } |
464 | 464 |
465 // We are closing the stream and will not process any further incoming bytes. | 465 // We are closing the stream and will not process any further incoming bytes. |
466 // As there may be more bytes in flight and we need to ensure that both | 466 // As there may be more bytes in flight and we need to ensure that both |
467 // endpoints have the same connection level flow control state, mark all | 467 // endpoints have the same connection level flow control state, mark all |
468 // unreceived or buffered bytes as consumed. | 468 // unreceived or buffered bytes as consumed. |
469 uint64 bytes_to_consume = flow_controller_.highest_received_byte_offset() - | 469 QuicByteCount bytes_to_consume = |
| 470 flow_controller_.highest_received_byte_offset() - |
470 flow_controller_.bytes_consumed(); | 471 flow_controller_.bytes_consumed(); |
471 AddBytesConsumed(bytes_to_consume); | 472 AddBytesConsumed(bytes_to_consume); |
472 } | 473 } |
473 | 474 |
474 void ReliableQuicStream::OnWindowUpdateFrame( | 475 void ReliableQuicStream::OnWindowUpdateFrame( |
475 const QuicWindowUpdateFrame& frame) { | 476 const QuicWindowUpdateFrame& frame) { |
476 if (!flow_controller_.IsEnabled()) { | 477 if (!flow_controller_.IsEnabled()) { |
477 DLOG(DFATAL) << "Flow control not enabled! " << version(); | 478 DLOG(DFATAL) << "Flow control not enabled! " << version(); |
478 return; | 479 return; |
479 } | 480 } |
480 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { | 481 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { |
481 // We can write again! | 482 // We can write again! |
482 // TODO(rjshade): This does not respect priorities (e.g. multiple | 483 // TODO(rjshade): This does not respect priorities (e.g. multiple |
483 // outstanding POSTs are unblocked on arrival of | 484 // outstanding POSTs are unblocked on arrival of |
484 // SHLO with initial window). | 485 // SHLO with initial window). |
485 // As long as the connection is not flow control blocked, we can write! | 486 // As long as the connection is not flow control blocked, we can write! |
486 OnCanWrite(); | 487 OnCanWrite(); |
487 } | 488 } |
488 } | 489 } |
489 | 490 |
490 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) { | 491 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset( |
| 492 QuicStreamOffset new_offset) { |
491 if (!flow_controller_.IsEnabled()) { | 493 if (!flow_controller_.IsEnabled()) { |
492 return false; | 494 return false; |
493 } | 495 } |
494 uint64 increment = | 496 uint64 increment = |
495 new_offset - flow_controller_.highest_received_byte_offset(); | 497 new_offset - flow_controller_.highest_received_byte_offset(); |
496 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { | 498 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { |
497 return false; | 499 return false; |
498 } | 500 } |
499 | 501 |
500 // If |new_offset| increased the stream flow controller's highest received | 502 // If |new_offset| increased the stream flow controller's highest received |
501 // offset, then we need to increase the connection flow controller's value | 503 // offset, then we need to increase the connection flow controller's value |
502 // by the incremental difference. | 504 // by the incremental difference. |
503 if (stream_contributes_to_connection_flow_control_) { | 505 if (stream_contributes_to_connection_flow_control_) { |
504 connection_flow_controller_->UpdateHighestReceivedOffset( | 506 connection_flow_controller_->UpdateHighestReceivedOffset( |
505 connection_flow_controller_->highest_received_byte_offset() + | 507 connection_flow_controller_->highest_received_byte_offset() + |
506 increment); | 508 increment); |
507 } | 509 } |
508 return true; | 510 return true; |
509 } | 511 } |
510 | 512 |
511 void ReliableQuicStream::AddBytesSent(uint64 bytes) { | 513 void ReliableQuicStream::AddBytesSent(QuicByteCount bytes) { |
512 if (flow_controller_.IsEnabled()) { | 514 if (flow_controller_.IsEnabled()) { |
513 flow_controller_.AddBytesSent(bytes); | 515 flow_controller_.AddBytesSent(bytes); |
514 if (stream_contributes_to_connection_flow_control_) { | 516 if (stream_contributes_to_connection_flow_control_) { |
515 connection_flow_controller_->AddBytesSent(bytes); | 517 connection_flow_controller_->AddBytesSent(bytes); |
516 } | 518 } |
517 } | 519 } |
518 } | 520 } |
519 | 521 |
520 void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { | 522 void ReliableQuicStream::AddBytesConsumed(QuicByteCount bytes) { |
521 if (flow_controller_.IsEnabled()) { | 523 if (flow_controller_.IsEnabled()) { |
522 // Only adjust stream level flow controller if we are still reading. | 524 // Only adjust stream level flow controller if we are still reading. |
523 if (!read_side_closed_) { | 525 if (!read_side_closed_) { |
524 flow_controller_.AddBytesConsumed(bytes); | 526 flow_controller_.AddBytesConsumed(bytes); |
525 } | 527 } |
526 | 528 |
527 if (stream_contributes_to_connection_flow_control_) { | 529 if (stream_contributes_to_connection_flow_control_) { |
528 connection_flow_controller_->AddBytesConsumed(bytes); | 530 connection_flow_controller_->AddBytesConsumed(bytes); |
529 } | 531 } |
530 } | 532 } |
531 } | 533 } |
532 | 534 |
533 void ReliableQuicStream::UpdateSendWindowOffset(uint64 new_window) { | 535 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { |
534 if (flow_controller_.UpdateSendWindowOffset(new_window)) { | 536 if (flow_controller_.UpdateSendWindowOffset(new_window)) { |
535 OnCanWrite(); | 537 OnCanWrite(); |
536 } | 538 } |
537 } | 539 } |
538 | 540 |
539 bool ReliableQuicStream::IsFlowControlBlocked() { | 541 bool ReliableQuicStream::IsFlowControlBlocked() { |
540 if (flow_controller_.IsBlocked()) { | 542 if (flow_controller_.IsBlocked()) { |
541 return true; | 543 return true; |
542 } | 544 } |
543 return stream_contributes_to_connection_flow_control_ && | 545 return stream_contributes_to_connection_flow_control_ && |
544 connection_flow_controller_->IsBlocked(); | 546 connection_flow_controller_->IsBlocked(); |
545 } | 547 } |
546 | 548 |
547 } // namespace net | 549 } // namespace net |
OLD | NEW |