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 "net/quic/quic_session.h" | 7 #include "net/quic/quic_session.h" |
8 #include "net/quic/quic_spdy_decompressor.h" | 8 #include "net/quic/quic_spdy_decompressor.h" |
9 #include "net/spdy/write_blocked_list.h" | 9 #include "net/spdy/write_blocked_list.h" |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 StringPiece(data, data_len).AppendToString(partial_data_buffer); | 34 StringPiece(data, data_len).AppendToString(partial_data_buffer); |
35 return data_len; | 35 return data_len; |
36 } | 36 } |
37 StringPiece(data, missing_size).AppendToString(partial_data_buffer); | 37 StringPiece(data, missing_size).AppendToString(partial_data_buffer); |
38 DCHECK_EQ(4u, partial_data_buffer->length()); | 38 DCHECK_EQ(4u, partial_data_buffer->length()); |
39 memcpy(result, partial_data_buffer->data(), 4); | 39 memcpy(result, partial_data_buffer->data(), 4); |
40 partial_data_buffer->clear(); | 40 partial_data_buffer->clear(); |
41 return missing_size; | 41 return missing_size; |
42 } | 42 } |
43 | 43 |
| 44 struct iovec MakeIovec(StringPiece data) { |
| 45 struct iovec iov = {const_cast<char*>(data.data()), |
| 46 static_cast<size_t>(data.size())}; |
| 47 return iov; |
| 48 } |
| 49 |
44 } // namespace | 50 } // namespace |
45 | 51 |
46 ReliableQuicStream::ReliableQuicStream(QuicStreamId id, | 52 ReliableQuicStream::ReliableQuicStream(QuicStreamId id, |
47 QuicSession* session) | 53 QuicSession* session) |
48 : sequencer_(this), | 54 : sequencer_(this), |
49 id_(id), | 55 id_(id), |
50 session_(session), | 56 session_(session), |
51 visitor_(NULL), | 57 visitor_(NULL), |
52 stream_bytes_read_(0), | 58 stream_bytes_read_(0), |
53 stream_bytes_written_(0), | 59 stream_bytes_written_(0), |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 } | 191 } |
186 | 192 |
187 QuicSpdyCompressor* ReliableQuicStream::compressor() { | 193 QuicSpdyCompressor* ReliableQuicStream::compressor() { |
188 return session_->compressor(); | 194 return session_->compressor(); |
189 } | 195 } |
190 | 196 |
191 bool ReliableQuicStream::GetSSLInfo(SSLInfo* ssl_info) { | 197 bool ReliableQuicStream::GetSSLInfo(SSLInfo* ssl_info) { |
192 return session_->GetSSLInfo(ssl_info); | 198 return session_->GetSSLInfo(ssl_info); |
193 } | 199 } |
194 | 200 |
195 QuicConsumedData ReliableQuicStream::WriteData(StringPiece data, bool fin) { | |
196 DCHECK(data.size() > 0 || fin); | |
197 return WriteOrBuffer(data, fin); | |
198 } | |
199 | |
200 | |
201 void ReliableQuicStream::set_priority(QuicPriority priority) { | 201 void ReliableQuicStream::set_priority(QuicPriority priority) { |
202 DCHECK_EQ(0u, stream_bytes_written_); | 202 DCHECK_EQ(0u, stream_bytes_written_); |
203 priority_ = priority; | 203 priority_ = priority; |
204 } | 204 } |
205 | 205 |
206 QuicConsumedData ReliableQuicStream::WriteOrBuffer(StringPiece data, bool fin) { | 206 void ReliableQuicStream::WriteOrBufferData(StringPiece data, bool fin) { |
| 207 DCHECK(data.size() > 0 || fin); |
207 DCHECK(!fin_buffered_); | 208 DCHECK(!fin_buffered_); |
208 | 209 |
209 QuicConsumedData consumed_data(0, false); | 210 QuicConsumedData consumed_data(0, false); |
210 fin_buffered_ = fin; | 211 fin_buffered_ = fin; |
211 | 212 |
212 if (queued_data_.empty()) { | 213 if (queued_data_.empty()) { |
213 consumed_data = WriteDataInternal(string(data.data(), data.length()), fin); | 214 struct iovec iov(MakeIovec(data)); |
| 215 consumed_data = WritevData(&iov, 1, fin, NULL); |
214 DCHECK_LE(consumed_data.bytes_consumed, data.length()); | 216 DCHECK_LE(consumed_data.bytes_consumed, data.length()); |
215 } | 217 } |
216 | 218 |
217 // If there's unconsumed data or an unconsumed fin, queue it. | 219 // If there's unconsumed data or an unconsumed fin, queue it. |
218 if (consumed_data.bytes_consumed < data.length() || | 220 if (consumed_data.bytes_consumed < data.length() || |
219 (fin && !consumed_data.fin_consumed)) { | 221 (fin && !consumed_data.fin_consumed)) { |
220 queued_data_.push_back( | 222 queued_data_.push_back( |
221 string(data.data() + consumed_data.bytes_consumed, | 223 string(data.data() + consumed_data.bytes_consumed, |
222 data.length() - consumed_data.bytes_consumed)); | 224 data.length() - consumed_data.bytes_consumed)); |
223 } | 225 } |
224 | |
225 return QuicConsumedData(data.size(), true); | |
226 } | 226 } |
227 | 227 |
228 void ReliableQuicStream::OnCanWrite() { | 228 void ReliableQuicStream::OnCanWrite() { |
229 bool fin = false; | 229 bool fin = false; |
230 while (!queued_data_.empty()) { | 230 while (!queued_data_.empty()) { |
231 const string& data = queued_data_.front(); | 231 const string& data = queued_data_.front(); |
232 if (queued_data_.size() == 1 && fin_buffered_) { | 232 if (queued_data_.size() == 1 && fin_buffered_) { |
233 fin = true; | 233 fin = true; |
234 } | 234 } |
235 QuicConsumedData consumed_data = WriteDataInternal(data, fin); | 235 struct iovec iov(MakeIovec(data)); |
| 236 QuicConsumedData consumed_data = WritevData(&iov, 1, fin, NULL); |
236 if (consumed_data.bytes_consumed == data.size() && | 237 if (consumed_data.bytes_consumed == data.size() && |
237 fin == consumed_data.fin_consumed) { | 238 fin == consumed_data.fin_consumed) { |
238 queued_data_.pop_front(); | 239 queued_data_.pop_front(); |
239 } else { | 240 } else { |
240 queued_data_.front().erase(0, consumed_data.bytes_consumed); | 241 queued_data_.front().erase(0, consumed_data.bytes_consumed); |
241 break; | 242 break; |
242 } | 243 } |
243 } | 244 } |
244 } | 245 } |
245 | 246 |
246 QuicConsumedData ReliableQuicStream::WriteDataInternal( | 247 QuicConsumedData ReliableQuicStream::WritevData( |
247 StringPiece data, bool fin) { | |
248 struct iovec iov = {const_cast<char*>(data.data()), | |
249 static_cast<size_t>(data.size())}; | |
250 return WritevDataInternal(&iov, 1, fin, NULL); | |
251 } | |
252 | |
253 QuicConsumedData ReliableQuicStream::WritevDataInternal( | |
254 const struct iovec* iov, | 248 const struct iovec* iov, |
255 int iov_count, | 249 int iov_count, |
256 bool fin, | 250 bool fin, |
257 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { | 251 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { |
258 if (write_side_closed_) { | 252 if (write_side_closed_) { |
259 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; | 253 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; |
260 return QuicConsumedData(0, false); | 254 return QuicConsumedData(0, false); |
261 } | 255 } |
262 | 256 |
263 size_t write_length = 0u; | 257 size_t write_length = 0u; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 if (data_len > 0 && headers_id_ == 0u) { | 505 if (data_len > 0 && headers_id_ == 0u) { |
512 // The headers ID has not yet been read. Strip it from the beginning of | 506 // The headers ID has not yet been read. Strip it from the beginning of |
513 // the data stream. | 507 // the data stream. |
514 total_bytes_parsed += StripUint32( | 508 total_bytes_parsed += StripUint32( |
515 data, data_len, &headers_id_and_priority_buffer_, &headers_id_); | 509 data, data_len, &headers_id_and_priority_buffer_, &headers_id_); |
516 } | 510 } |
517 return total_bytes_parsed; | 511 return total_bytes_parsed; |
518 } | 512 } |
519 | 513 |
520 } // namespace net | 514 } // namespace net |
OLD | NEW |