Chromium Code Reviews| 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 "content/browser/byte_stream.h" | 5 #include "content/browser/byte_stream.h" |
| 6 | 6 |
| 7 #include <deque> | 7 #include <deque> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 void SetPeer(ByteStreamReaderImpl* peer, | 54 void SetPeer(ByteStreamReaderImpl* peer, |
| 55 scoped_refptr<base::SequencedTaskRunner> peer_task_runner, | 55 scoped_refptr<base::SequencedTaskRunner> peer_task_runner, |
| 56 scoped_refptr<LifetimeFlag> peer_lifetime_flag); | 56 scoped_refptr<LifetimeFlag> peer_lifetime_flag); |
| 57 | 57 |
| 58 // Overridden from ByteStreamWriter. | 58 // Overridden from ByteStreamWriter. |
| 59 virtual bool Write(scoped_refptr<net::IOBuffer> buffer, | 59 virtual bool Write(scoped_refptr<net::IOBuffer> buffer, |
| 60 size_t byte_count) OVERRIDE; | 60 size_t byte_count) OVERRIDE; |
| 61 virtual void Flush() OVERRIDE; | 61 virtual void Flush() OVERRIDE; |
| 62 virtual void Close(int status) OVERRIDE; | 62 virtual void Close(int status) OVERRIDE; |
| 63 virtual void RegisterCallback(const base::Closure& source_callback) OVERRIDE; | 63 virtual void RegisterCallback(const base::Closure& source_callback) OVERRIDE; |
| 64 virtual size_t GetTotalBufferedBytes() const OVERRIDE; | |
| 64 | 65 |
| 65 // PostTask target from |ByteStreamReaderImpl::MaybeUpdateInput|. | 66 // PostTask target from |ByteStreamReaderImpl::MaybeUpdateInput|. |
| 66 static void UpdateWindow(scoped_refptr<LifetimeFlag> lifetime_flag, | 67 static void UpdateWindow(scoped_refptr<LifetimeFlag> lifetime_flag, |
| 67 ByteStreamWriterImpl* target, | 68 ByteStreamWriterImpl* target, |
| 68 size_t bytes_consumed); | 69 size_t bytes_consumed); |
| 69 | 70 |
| 70 private: | 71 private: |
| 71 // Called from UpdateWindow when object existence has been validated. | 72 // Called from UpdateWindow when object existence has been validated. |
| 72 void UpdateWindowInternal(size_t bytes_consumed); | 73 void UpdateWindowInternal(size_t bytes_consumed); |
| 73 | 74 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 scoped_refptr<LifetimeFlag> peer_lifetime_flag) { | 203 scoped_refptr<LifetimeFlag> peer_lifetime_flag) { |
| 203 peer_ = peer; | 204 peer_ = peer; |
| 204 peer_task_runner_ = peer_task_runner; | 205 peer_task_runner_ = peer_task_runner; |
| 205 peer_lifetime_flag_ = peer_lifetime_flag; | 206 peer_lifetime_flag_ = peer_lifetime_flag; |
| 206 } | 207 } |
| 207 | 208 |
| 208 bool ByteStreamWriterImpl::Write( | 209 bool ByteStreamWriterImpl::Write( |
| 209 scoped_refptr<net::IOBuffer> buffer, size_t byte_count) { | 210 scoped_refptr<net::IOBuffer> buffer, size_t byte_count) { |
| 210 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 211 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 211 | 212 |
| 213 // Check overflow. | |
| 214 size_t space_limit = std::numeric_limits<size_t>::max() - | |
| 215 output_size_used_ - input_contents_size_; | |
|
Charlie Reis
2013/08/20 22:24:52
Any reason not to use GetTotalBufferedBytes here?
tyoshino (SeeGerritForStatus)
2013/08/21 05:37:28
No reason. Replaced.
| |
| 216 if (byte_count > space_limit) { | |
| 217 // TODO(tyoshino): Tell the user that Write() failed. | |
| 218 // Ignore input. | |
| 219 return false; | |
| 220 } | |
| 221 | |
| 212 input_contents_.push_back(std::make_pair(buffer, byte_count)); | 222 input_contents_.push_back(std::make_pair(buffer, byte_count)); |
| 213 input_contents_size_ += byte_count; | 223 input_contents_size_ += byte_count; |
| 214 | 224 |
| 215 // Arbitrarily, we buffer to a third of the total size before sending. | 225 // Arbitrarily, we buffer to a third of the total size before sending. |
| 216 if (input_contents_size_ > total_buffer_size_ / kFractionBufferBeforeSending) | 226 if (input_contents_size_ > total_buffer_size_ / kFractionBufferBeforeSending) |
| 217 PostToPeer(false, 0); | 227 PostToPeer(false, 0); |
| 218 | 228 |
| 219 return (input_contents_size_ + output_size_used_ <= total_buffer_size_); | 229 return GetTotalBufferedBytes() <= total_buffer_size_; |
| 220 } | 230 } |
| 221 | 231 |
| 222 void ByteStreamWriterImpl::Flush() { | 232 void ByteStreamWriterImpl::Flush() { |
| 223 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 233 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 224 if (input_contents_size_ > 0) | 234 if (input_contents_size_ > 0) |
| 225 PostToPeer(false, 0); | 235 PostToPeer(false, 0); |
| 226 } | 236 } |
| 227 | 237 |
| 228 void ByteStreamWriterImpl::Close(int status) { | 238 void ByteStreamWriterImpl::Close(int status) { |
| 229 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 239 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 230 PostToPeer(true, status); | 240 PostToPeer(true, status); |
| 231 } | 241 } |
| 232 | 242 |
| 233 void ByteStreamWriterImpl::RegisterCallback( | 243 void ByteStreamWriterImpl::RegisterCallback( |
| 234 const base::Closure& source_callback) { | 244 const base::Closure& source_callback) { |
| 235 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 245 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 236 space_available_callback_ = source_callback; | 246 space_available_callback_ = source_callback; |
| 237 } | 247 } |
| 238 | 248 |
| 249 size_t ByteStreamWriterImpl::GetTotalBufferedBytes() const { | |
| 250 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | |
| 251 // This sum doesn't overflow since Write() fails if this sum is going to | |
| 252 // overflow. | |
| 253 return input_contents_size_ + output_size_used_; | |
| 254 } | |
| 255 | |
| 239 // static | 256 // static |
| 240 void ByteStreamWriterImpl::UpdateWindow( | 257 void ByteStreamWriterImpl::UpdateWindow( |
| 241 scoped_refptr<LifetimeFlag> lifetime_flag, ByteStreamWriterImpl* target, | 258 scoped_refptr<LifetimeFlag> lifetime_flag, ByteStreamWriterImpl* target, |
| 242 size_t bytes_consumed) { | 259 size_t bytes_consumed) { |
| 243 // If the target object isn't alive anymore, we do nothing. | 260 // If the target object isn't alive anymore, we do nothing. |
| 244 if (!lifetime_flag->is_alive) return; | 261 if (!lifetime_flag->is_alive) return; |
| 245 | 262 |
| 246 target->UpdateWindowInternal(bytes_consumed); | 263 target->UpdateWindowInternal(bytes_consumed); |
| 247 } | 264 } |
| 248 | 265 |
| 249 void ByteStreamWriterImpl::UpdateWindowInternal(size_t bytes_consumed) { | 266 void ByteStreamWriterImpl::UpdateWindowInternal(size_t bytes_consumed) { |
| 250 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 267 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 268 | |
| 269 bool was_above_limit = | |
| 270 input_contents_size_ + output_size_used_ > total_buffer_size_; | |
|
Charlie Reis
2013/08/20 22:24:52
Again, please use GetTotalBufferedBytes here and b
tyoshino (SeeGerritForStatus)
2013/08/21 05:37:28
Done.
| |
| 271 | |
| 251 DCHECK_GE(output_size_used_, bytes_consumed); | 272 DCHECK_GE(output_size_used_, bytes_consumed); |
| 252 output_size_used_ -= bytes_consumed; | 273 output_size_used_ -= bytes_consumed; |
| 253 | 274 |
| 254 // Callback if we were above the limit and we're now <= to it. | 275 // Callback if we were above the limit and we're now <= to it. |
| 255 size_t total_known_size_used = | 276 bool no_longer_above_limit = |
| 256 input_contents_size_ + output_size_used_; | 277 input_contents_size_ + output_size_used_ <= total_buffer_size_; |
| 257 | 278 |
| 258 if (total_known_size_used <= total_buffer_size_ && | 279 if (no_longer_above_limit && was_above_limit && |
| 259 (total_known_size_used + bytes_consumed > total_buffer_size_) && | |
| 260 !space_available_callback_.is_null()) | 280 !space_available_callback_.is_null()) |
| 261 space_available_callback_.Run(); | 281 space_available_callback_.Run(); |
| 262 } | 282 } |
| 263 | 283 |
| 264 void ByteStreamWriterImpl::PostToPeer(bool complete, int status) { | 284 void ByteStreamWriterImpl::PostToPeer(bool complete, int status) { |
| 265 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); | 285 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); |
| 266 // Valid contexts in which to call. | 286 // Valid contexts in which to call. |
| 267 DCHECK(complete || 0 != input_contents_size_); | 287 DCHECK(complete || 0 != input_contents_size_); |
| 268 | 288 |
| 269 scoped_ptr<ContentVector> transfer_buffer; | 289 scoped_ptr<ContentVector> transfer_buffer; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 ByteStreamReaderImpl* out = new ByteStreamReaderImpl( | 452 ByteStreamReaderImpl* out = new ByteStreamReaderImpl( |
| 433 output_task_runner, output_flag, buffer_size); | 453 output_task_runner, output_flag, buffer_size); |
| 434 | 454 |
| 435 in->SetPeer(out, output_task_runner, output_flag); | 455 in->SetPeer(out, output_task_runner, output_flag); |
| 436 out->SetPeer(in, input_task_runner, input_flag); | 456 out->SetPeer(in, input_task_runner, input_flag); |
| 437 input->reset(in); | 457 input->reset(in); |
| 438 output->reset(out); | 458 output->reset(out); |
| 439 } | 459 } |
| 440 | 460 |
| 441 } // namespace content | 461 } // namespace content |
| OLD | NEW |