| 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 |