Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/spdy/bidirectional_stream_spdy_impl.h" | 5 #include "net/spdy/bidirectional_stream_spdy_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 read_buffer_ = buf; | 101 read_buffer_ = buf; |
| 102 read_buffer_len_ = buf_len; | 102 read_buffer_len_ = buf_len; |
| 103 return ERR_IO_PENDING; | 103 return ERR_IO_PENDING; |
| 104 } | 104 } |
| 105 | 105 |
| 106 void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, | 106 void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, |
| 107 int length, | 107 int length, |
| 108 bool end_stream) { | 108 bool end_stream) { |
| 109 DCHECK(length > 0 || (length == 0 && end_stream)); | 109 DCHECK(length > 0 || (length == 0 && end_stream)); |
| 110 | 110 |
| 111 if (!stream_) { | 111 if (MaybeHandleStreamClosedInSendData()) |
| 112 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | |
| 113 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 114 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | |
| 115 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | |
| 116 return; | 112 return; |
| 117 } | |
| 118 | 113 |
| 119 DCHECK(!stream_closed_); | 114 DCHECK(!stream_closed_); |
| 120 stream_->SendData(data.get(), length, | 115 stream_->SendData(data.get(), length, |
| 121 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); | 116 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); |
| 122 } | 117 } |
| 123 | 118 |
| 124 void BidirectionalStreamSpdyImpl::SendvData( | 119 void BidirectionalStreamSpdyImpl::SendvData( |
| 125 const std::vector<scoped_refptr<IOBuffer>>& buffers, | 120 const std::vector<scoped_refptr<IOBuffer>>& buffers, |
| 126 const std::vector<int>& lengths, | 121 const std::vector<int>& lengths, |
| 127 bool end_stream) { | 122 bool end_stream) { |
| 128 DCHECK_EQ(buffers.size(), lengths.size()); | 123 DCHECK_EQ(buffers.size(), lengths.size()); |
| 129 | 124 |
| 130 if (!stream_) { | 125 if (MaybeHandleStreamClosedInSendData()) |
| 131 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | |
| 132 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 133 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | |
| 134 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | |
| 135 return; | 126 return; |
| 136 } | |
| 137 | 127 |
| 138 DCHECK(!stream_closed_); | 128 DCHECK(!stream_closed_); |
| 139 int total_len = 0; | 129 int total_len = 0; |
| 140 for (int len : lengths) { | 130 for (int len : lengths) { |
| 141 total_len += len; | 131 total_len += len; |
| 142 } | 132 } |
| 143 | 133 |
| 144 pending_combined_buffer_ = new net::IOBuffer(total_len); | 134 pending_combined_buffer_ = new net::IOBuffer(total_len); |
| 145 int len = 0; | 135 int len = 0; |
| 146 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. | 136 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 if (delegate_) { | 297 if (delegate_) { |
| 308 BidirectionalStreamImpl::Delegate* delegate = delegate_; | 298 BidirectionalStreamImpl::Delegate* delegate = delegate_; |
| 309 delegate_ = nullptr; | 299 delegate_ = nullptr; |
| 310 // Cancel any pending callback. | 300 // Cancel any pending callback. |
| 311 weak_factory_.InvalidateWeakPtrs(); | 301 weak_factory_.InvalidateWeakPtrs(); |
| 312 delegate->OnFailed(rv); | 302 delegate->OnFailed(rv); |
| 313 // |this| can be null when returned from delegate. | 303 // |this| can be null when returned from delegate. |
| 314 } | 304 } |
| 315 } | 305 } |
| 316 | 306 |
| 307 void BidirectionalStreamSpdyImpl::NotifyDataSent() { | |
| 308 if (delegate_) | |
| 309 delegate_->OnDataSent(); | |
| 310 } | |
| 311 | |
| 317 void BidirectionalStreamSpdyImpl::ResetStream() { | 312 void BidirectionalStreamSpdyImpl::ResetStream() { |
| 318 if (!stream_) | 313 if (!stream_) |
| 319 return; | 314 return; |
| 320 if (!stream_->IsClosed()) { | 315 if (!stream_->IsClosed()) { |
| 321 // This sends a RST to the remote. | 316 // This sends a RST to the remote. |
| 322 stream_->DetachDelegate(); | 317 stream_->DetachDelegate(); |
| 323 DCHECK(!stream_); | 318 DCHECK(!stream_); |
| 324 } else { | 319 } else { |
| 325 // Stream is already closed, so it is not legal to call DetachDelegate. | 320 // Stream is already closed, so it is not legal to call DetachDelegate. |
| 326 stream_.reset(); | 321 stream_.reset(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 } | 361 } |
| 367 | 362 |
| 368 bool BidirectionalStreamSpdyImpl::ShouldWaitForMoreBufferedData() const { | 363 bool BidirectionalStreamSpdyImpl::ShouldWaitForMoreBufferedData() const { |
| 369 if (stream_closed_) | 364 if (stream_closed_) |
| 370 return false; | 365 return false; |
| 371 DCHECK_GT(read_buffer_len_, 0); | 366 DCHECK_GT(read_buffer_len_, 0); |
| 372 return read_data_queue_.GetTotalSize() < | 367 return read_data_queue_.GetTotalSize() < |
| 373 static_cast<size_t>(read_buffer_len_); | 368 static_cast<size_t>(read_buffer_len_); |
| 374 } | 369 } |
| 375 | 370 |
| 371 bool BidirectionalStreamSpdyImpl::MaybeHandleStreamClosedInSendData() { | |
| 372 if (stream_) | |
| 373 return false; | |
| 374 // If |stream_| is closed without an error, blackhole any any write data. | |
| 375 if (stream_closed_ && closed_stream_status_ == OK) { | |
|
kapishnikov
2016/10/28 16:11:00
If the stream was closed because all data were sen
| |
| 376 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 377 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyDataSent, | |
| 378 weak_factory_.GetWeakPtr())); | |
| 379 return true; | |
| 380 } | |
| 381 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | |
| 382 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 383 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | |
| 384 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | |
| 385 return true; | |
| 386 } | |
| 387 | |
| 376 } // namespace net | 388 } // namespace net |
| OLD | NEW |