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/chromium/bidirectional_stream_spdy_impl.h" | 5 #include "net/spdy/chromium/bidirectional_stream_spdy_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } else if (stream_closed_) { | 103 } else if (stream_closed_) { |
104 return closed_stream_status_; | 104 return closed_stream_status_; |
105 } | 105 } |
106 // Read will complete asynchronously and Delegate::OnReadCompleted will be | 106 // Read will complete asynchronously and Delegate::OnReadCompleted will be |
107 // called upon completion. | 107 // called upon completion. |
108 read_buffer_ = buf; | 108 read_buffer_ = buf; |
109 read_buffer_len_ = buf_len; | 109 read_buffer_len_ = buf_len; |
110 return ERR_IO_PENDING; | 110 return ERR_IO_PENDING; |
111 } | 111 } |
112 | 112 |
113 void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, | |
114 int length, | |
115 bool end_stream) { | |
116 DCHECK(length > 0 || (length == 0 && end_stream)); | |
117 DCHECK(!write_pending_); | |
118 | |
119 if (written_end_of_stream_) { | |
120 LOG(ERROR) << "Writing after end of stream is written."; | |
121 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
122 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | |
123 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | |
124 return; | |
125 } | |
126 | |
127 write_pending_ = true; | |
128 written_end_of_stream_ = end_stream; | |
129 if (MaybeHandleStreamClosedInSendData()) | |
130 return; | |
131 | |
132 DCHECK(!stream_closed_); | |
133 stream_->SendData(data.get(), length, | |
134 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); | |
135 } | |
136 | |
137 void BidirectionalStreamSpdyImpl::SendvData( | 113 void BidirectionalStreamSpdyImpl::SendvData( |
138 const std::vector<scoped_refptr<IOBuffer>>& buffers, | 114 const std::vector<scoped_refptr<IOBuffer>>& buffers, |
139 const std::vector<int>& lengths, | 115 const std::vector<int>& lengths, |
140 bool end_stream) { | 116 bool end_stream) { |
141 DCHECK_EQ(buffers.size(), lengths.size()); | 117 DCHECK_EQ(buffers.size(), lengths.size()); |
142 DCHECK(!write_pending_); | 118 DCHECK(!write_pending_); |
143 | 119 |
144 if (written_end_of_stream_) { | 120 if (written_end_of_stream_) { |
145 LOG(ERROR) << "Writing after end of stream is written."; | 121 LOG(ERROR) << "Writing after end of stream is written."; |
146 base::ThreadTaskRunnerHandle::Get()->PostTask( | 122 base::ThreadTaskRunnerHandle::Get()->PostTask( |
147 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | 123 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, |
148 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 124 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
149 return; | 125 return; |
150 } | 126 } |
151 | 127 |
152 write_pending_ = true; | 128 write_pending_ = true; |
153 written_end_of_stream_ = end_stream; | 129 written_end_of_stream_ = end_stream; |
154 if (MaybeHandleStreamClosedInSendData()) | 130 if (MaybeHandleStreamClosedInSendData()) |
155 return; | 131 return; |
156 | 132 |
157 DCHECK(!stream_closed_); | 133 DCHECK(!stream_closed_); |
158 int total_len = 0; | 134 int total_len = 0; |
159 for (int len : lengths) { | 135 for (int len : lengths) { |
160 total_len += len; | 136 total_len += len; |
161 } | 137 } |
162 | 138 |
163 pending_combined_buffer_ = new net::IOBuffer(total_len); | 139 if (buffers.size() == 1) { |
164 int len = 0; | 140 pending_combined_buffer_ = buffers[0]; |
165 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. | 141 } else { |
166 for (size_t i = 0; i < buffers.size(); ++i) { | 142 pending_combined_buffer_ = new net::IOBuffer(total_len); |
167 memcpy(pending_combined_buffer_->data() + len, buffers[i]->data(), | 143 int len = 0; |
168 lengths[i]); | 144 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. |
169 len += lengths[i]; | 145 for (size_t i = 0; i < buffers.size(); ++i) { |
| 146 memcpy(pending_combined_buffer_->data() + len, buffers[i]->data(), |
| 147 lengths[i]); |
| 148 len += lengths[i]; |
| 149 } |
170 } | 150 } |
171 stream_->SendData(pending_combined_buffer_.get(), total_len, | 151 stream_->SendData(pending_combined_buffer_.get(), total_len, |
172 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); | 152 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); |
173 } | 153 } |
174 | 154 |
175 NextProto BidirectionalStreamSpdyImpl::GetProtocol() const { | 155 NextProto BidirectionalStreamSpdyImpl::GetProtocol() const { |
176 return negotiated_protocol_; | 156 return negotiated_protocol_; |
177 } | 157 } |
178 | 158 |
179 int64_t BidirectionalStreamSpdyImpl::GetTotalReceivedBytes() const { | 159 int64_t BidirectionalStreamSpdyImpl::GetTotalReceivedBytes() const { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 return true; | 395 return true; |
416 } | 396 } |
417 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | 397 LOG(ERROR) << "Trying to send data after stream has been destroyed."; |
418 base::ThreadTaskRunnerHandle::Get()->PostTask( | 398 base::ThreadTaskRunnerHandle::Get()->PostTask( |
419 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, | 399 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, |
420 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 400 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
421 return true; | 401 return true; |
422 } | 402 } |
423 | 403 |
424 } // namespace net | 404 } // namespace net |
OLD | NEW |