| 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_ack_listener_interface.h" | 9 #include "net/quic/quic_ack_listener_interface.h" |
| 10 #include "net/quic/quic_flags.h" | 10 #include "net/quic/quic_flags.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 | 45 |
| 46 ReliableQuicStream::PendingData::PendingData( | 46 ReliableQuicStream::PendingData::PendingData( |
| 47 string data_in, | 47 string data_in, |
| 48 QuicAckListenerInterface* ack_listener_in) | 48 QuicAckListenerInterface* ack_listener_in) |
| 49 : data(data_in), offset(0), ack_listener(ack_listener_in) {} | 49 : data(data_in), offset(0), ack_listener(ack_listener_in) {} |
| 50 | 50 |
| 51 ReliableQuicStream::PendingData::~PendingData() { | 51 ReliableQuicStream::PendingData::~PendingData() { |
| 52 } | 52 } |
| 53 | 53 |
| 54 ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session) | 54 ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session) |
| 55 : sequencer_(this, session->connection()->clock()), | 55 : queued_data_bytes_(0), |
| 56 sequencer_(this, session->connection()->clock()), |
| 56 id_(id), | 57 id_(id), |
| 57 session_(session), | 58 session_(session), |
| 58 stream_bytes_read_(0), | 59 stream_bytes_read_(0), |
| 59 stream_bytes_written_(0), | 60 stream_bytes_written_(0), |
| 60 stream_error_(QUIC_STREAM_NO_ERROR), | 61 stream_error_(QUIC_STREAM_NO_ERROR), |
| 61 connection_error_(QUIC_NO_ERROR), | 62 connection_error_(QUIC_NO_ERROR), |
| 62 read_side_closed_(false), | 63 read_side_closed_(false), |
| 63 write_side_closed_(false), | 64 write_side_closed_(false), |
| 64 fin_buffered_(false), | 65 fin_buffered_(false), |
| 65 fin_sent_(false), | 66 fin_sent_(false), |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 if (queued_data_.empty()) { | 210 if (queued_data_.empty()) { |
| 210 struct iovec iov(MakeIovec(data)); | 211 struct iovec iov(MakeIovec(data)); |
| 211 consumed_data = WritevData(&iov, 1, fin, ack_listener); | 212 consumed_data = WritevData(&iov, 1, fin, ack_listener); |
| 212 DCHECK_LE(consumed_data.bytes_consumed, data.length()); | 213 DCHECK_LE(consumed_data.bytes_consumed, data.length()); |
| 213 } | 214 } |
| 214 | 215 |
| 215 // If there's unconsumed data or an unconsumed fin, queue it. | 216 // If there's unconsumed data or an unconsumed fin, queue it. |
| 216 if (consumed_data.bytes_consumed < data.length() || | 217 if (consumed_data.bytes_consumed < data.length() || |
| 217 (fin && !consumed_data.fin_consumed)) { | 218 (fin && !consumed_data.fin_consumed)) { |
| 218 StringPiece remainder(data.substr(consumed_data.bytes_consumed)); | 219 StringPiece remainder(data.substr(consumed_data.bytes_consumed)); |
| 220 queued_data_bytes_ += remainder.size(); |
| 219 queued_data_.push_back(PendingData(remainder.as_string(), ack_listener)); | 221 queued_data_.push_back(PendingData(remainder.as_string(), ack_listener)); |
| 220 } | 222 } |
| 221 } | 223 } |
| 222 | 224 |
| 223 void ReliableQuicStream::OnCanWrite() { | 225 void ReliableQuicStream::OnCanWrite() { |
| 224 bool fin = false; | 226 bool fin = false; |
| 225 while (!queued_data_.empty()) { | 227 while (!queued_data_.empty()) { |
| 226 PendingData* pending_data = &queued_data_.front(); | 228 PendingData* pending_data = &queued_data_.front(); |
| 227 QuicAckListenerInterface* ack_listener = pending_data->ack_listener.get(); | 229 QuicAckListenerInterface* ack_listener = pending_data->ack_listener.get(); |
| 228 if (queued_data_.size() == 1 && fin_buffered_) { | 230 if (queued_data_.size() == 1 && fin_buffered_) { |
| 229 fin = true; | 231 fin = true; |
| 230 } | 232 } |
| 231 if (pending_data->offset > 0 && | 233 if (pending_data->offset > 0 && |
| 232 pending_data->offset >= pending_data->data.size()) { | 234 pending_data->offset >= pending_data->data.size()) { |
| 233 // This should be impossible because offset tracks the amount of | 235 // This should be impossible because offset tracks the amount of |
| 234 // pending_data written thus far. | 236 // pending_data written thus far. |
| 235 LOG(DFATAL) << "Pending offset is beyond available data. offset: " | 237 LOG(DFATAL) << "Pending offset is beyond available data. offset: " |
| 236 << pending_data->offset | 238 << pending_data->offset |
| 237 << " vs: " << pending_data->data.size(); | 239 << " vs: " << pending_data->data.size(); |
| 238 return; | 240 return; |
| 239 } | 241 } |
| 240 size_t remaining_len = pending_data->data.size() - pending_data->offset; | 242 size_t remaining_len = pending_data->data.size() - pending_data->offset; |
| 241 struct iovec iov = { | 243 struct iovec iov = { |
| 242 const_cast<char*>(pending_data->data.data()) + pending_data->offset, | 244 const_cast<char*>(pending_data->data.data()) + pending_data->offset, |
| 243 remaining_len}; | 245 remaining_len}; |
| 244 QuicConsumedData consumed_data = WritevData(&iov, 1, fin, ack_listener); | 246 QuicConsumedData consumed_data = WritevData(&iov, 1, fin, ack_listener); |
| 247 queued_data_bytes_ -= consumed_data.bytes_consumed; |
| 245 if (consumed_data.bytes_consumed == remaining_len && | 248 if (consumed_data.bytes_consumed == remaining_len && |
| 246 fin == consumed_data.fin_consumed) { | 249 fin == consumed_data.fin_consumed) { |
| 247 queued_data_.pop_front(); | 250 queued_data_.pop_front(); |
| 248 } else { | 251 } else { |
| 249 if (consumed_data.bytes_consumed > 0) { | 252 if (consumed_data.bytes_consumed > 0) { |
| 250 pending_data->offset += consumed_data.bytes_consumed; | 253 pending_data->offset += consumed_data.bytes_consumed; |
| 251 } | 254 } |
| 252 break; | 255 break; |
| 253 } | 256 } |
| 254 } | 257 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 } | 458 } |
| 456 } | 459 } |
| 457 | 460 |
| 458 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { | 461 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { |
| 459 if (flow_controller_.UpdateSendWindowOffset(new_window)) { | 462 if (flow_controller_.UpdateSendWindowOffset(new_window)) { |
| 460 OnCanWrite(); | 463 OnCanWrite(); |
| 461 } | 464 } |
| 462 } | 465 } |
| 463 | 466 |
| 464 } // namespace net | 467 } // namespace net |
| OLD | NEW |