Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: content/browser/byte_stream.cc

Issue 22908008: Limit the total memory usage for Stream instances (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove unnecessary <limits> Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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() -
Charlie Reis 2013/08/21 19:13:56 Can you add a comment explaining why this class us
tyoshino (SeeGerritForStatus) 2013/08/22 02:19:02 ByteStream is used by other component (content/bro
215 GetTotalBufferedBytes();
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 = GetTotalBufferedBytes() > total_buffer_size_;
270
251 DCHECK_GE(output_size_used_, bytes_consumed); 271 DCHECK_GE(output_size_used_, bytes_consumed);
252 output_size_used_ -= bytes_consumed; 272 output_size_used_ -= bytes_consumed;
253 273
254 // Callback if we were above the limit and we're now <= to it. 274 // Callback if we were above the limit and we're now <= to it.
255 size_t total_known_size_used = 275 bool no_longer_above_limit = GetTotalBufferedBytes() <= total_buffer_size_;
256 input_contents_size_ + output_size_used_;
257 276
258 if (total_known_size_used <= total_buffer_size_ && 277 if (no_longer_above_limit && was_above_limit &&
259 (total_known_size_used + bytes_consumed > total_buffer_size_) &&
260 !space_available_callback_.is_null()) 278 !space_available_callback_.is_null())
261 space_available_callback_.Run(); 279 space_available_callback_.Run();
262 } 280 }
263 281
264 void ByteStreamWriterImpl::PostToPeer(bool complete, int status) { 282 void ByteStreamWriterImpl::PostToPeer(bool complete, int status) {
265 DCHECK(my_task_runner_->RunsTasksOnCurrentThread()); 283 DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
266 // Valid contexts in which to call. 284 // Valid contexts in which to call.
267 DCHECK(complete || 0 != input_contents_size_); 285 DCHECK(complete || 0 != input_contents_size_);
268 286
269 scoped_ptr<ContentVector> transfer_buffer; 287 scoped_ptr<ContentVector> transfer_buffer;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 ByteStreamReaderImpl* out = new ByteStreamReaderImpl( 450 ByteStreamReaderImpl* out = new ByteStreamReaderImpl(
433 output_task_runner, output_flag, buffer_size); 451 output_task_runner, output_flag, buffer_size);
434 452
435 in->SetPeer(out, output_task_runner, output_flag); 453 in->SetPeer(out, output_task_runner, output_flag);
436 out->SetPeer(in, input_task_runner, input_flag); 454 out->SetPeer(in, input_task_runner, input_flag);
437 input->reset(in); 455 input->reset(in);
438 output->reset(out); 456 output->reset(out);
439 } 457 }
440 458
441 } // namespace content 459 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698