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

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

Issue 10074001: Initial implementation of the ByteStream refactor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/download/byte_stream.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9
10 namespace content {
11
12 ByteStream::ByteStream()
13 : buffer_size_(kDefaultBufferSize),
14 data_size_(0),
15 is_complete_(false),
16 source_status_(DOWNLOAD_INTERRUPT_REASON_NONE) { }
17
18 void ByteStream::SetBufferSize(size_t buffer_size) {
19 buffer_size_ = buffer_size;
20 }
21
22 bool ByteStream::AddData(scoped_refptr<net::IOBuffer> buffer,
23 size_t byte_count) {
24 base::AutoLock auto_lock(lock_);
25
26 if (data_size_ == 0 && byte_count > 0 && sink_task_runner_.get() != NULL)
ahendrickson 2012/04/16 15:14:27 Nit: Add braces for multi-line 'if' bodies.
Randy Smith (Not in Mondays) 2012/04/18 19:10:38 Ooops. But already done in a later PS.
27 // Nothing actually touches the data on this object can be
ahendrickson 2012/04/16 15:14:27 *Nothing that
Randy Smith (Not in Mondays) 2012/04/18 19:10:38 Done.
28 // executed until we drop the lock, so it's ok to
29 // dispatch this before we actually add the data.
30 sink_task_runner_->PostTask(
31 FROM_HERE, base::Bind(&content::ByteStream::RunSinkCallback,
32 this, sink_task_runner_));
33
34 // Take manual (not enforced by compiler via scoped_*) ownership of data.
35 contents_.push_back(std::make_pair(buffer, byte_count));
36 data_size_ += byte_count;
37 return (data_size_ < buffer_size_);
38 }
39
40 void ByteStream::SourceComplete(DownloadInterruptReason status) {
41 base::AutoLock auto_lock(lock_);
42
43 is_complete_ = true;
44 source_status_ = status;
45 // If contents_ is non-empty, a callback has already been posted.
46 if (contents_.empty() && sink_task_runner_.get() != NULL)
ahendrickson 2012/04/16 15:14:27 Nit: Add braces.
Randy Smith (Not in Mondays) 2012/04/18 19:10:38 Done.
47 sink_task_runner_->PostTask(
48 FROM_HERE, base::Bind(&content::ByteStream::RunSinkCallback,
49 this, sink_task_runner_));
50 }
51
52 bool ByteStream::IsFull() {
53 base::AutoLock auto_lock(lock_);
54
55 return (data_size_ >= buffer_size_);
56 }
57
58 void ByteStream::RegisterSourceCallback(
59 scoped_refptr<base::TaskRunner> source_task_runner,
60 ByteStreamCallback source_callback) {
61 base::AutoLock auto_lock(lock_);
62
63 source_task_runner_ = source_task_runner;
64 source_callback_ = source_callback;
65 }
66
67 ByteStream::StreamState ByteStream::GetData(scoped_refptr<net::IOBuffer>* data,
68 size_t* length) {
69 base::AutoLock auto_lock(lock_);
70
71 if (contents_.empty()) {
72 if (is_complete_)
73 return STREAM_COMPLETE;
74 return STREAM_EMPTY;
75 }
76
77 if (data_size_ >= buffer_size_ &&
78 data_size_ - contents_.front().second < buffer_size_ &&
79 source_task_runner_.get() != NULL)
ahendrickson 2012/04/16 15:14:27 Nit: Add braces.
Randy Smith (Not in Mondays) 2012/04/18 19:10:38 Done.
80 // Nothing actually touches the data on this object can be
ahendrickson 2012/04/16 15:14:27 *Nothing that
Randy Smith (Not in Mondays) 2012/04/18 19:10:38 Done.
81 // executed until we drop the lock, so it's ok to
82 // dispatch this before we actually take the data.
83 source_task_runner_->PostTask(FROM_HERE, base::Bind(
84 &content::ByteStream::RunSourceCallback, this, source_task_runner_));
85
86 *data = contents_.front().first;
87 *length = contents_.front().second;
88 contents_.pop_front();
89 data_size_ -= *length;
90 return STREAM_NON_EMPTY;
91 }
92
93 DownloadInterruptReason ByteStream::GetSourceResult () {
94 base::AutoLock auto_lock(lock_);
95
96 return source_status_;
97 }
98
99 void ByteStream::RegisterSinkCallback(
100 scoped_refptr<base::TaskRunner> sink_task_runner,
101 ByteStreamCallback sink_callback) {
102 base::AutoLock auto_lock(lock_);
103
104 sink_task_runner_ = sink_task_runner;
105 sink_callback_ = sink_callback;
106 }
107
108 ByteStream::~ByteStream() {
109 }
110
111 void ByteStream::RunSourceCallback(
112 scoped_refptr<base::TaskRunner> target_runner) {
113 base::Closure callback;
114 {
115 base::AutoLock auto_lock(lock_);
116
117 // If the target_runner has been updated, that implies an access to
118 // the class, so we can drop this request on the floor. (The
119 // alternative would be to forward it on to the new task runner.)
120 if (target_runner.get() != source_task_runner_.get())
121 return;
122
123 if (source_callback_.is_null())
124 return;
125
126 callback = source_callback_;
127 }
128
129 // Run unlocked to allow caller to call back into us.
130 callback.Run();
131 }
132
133 void ByteStream::RunSinkCallback(
134 scoped_refptr<base::TaskRunner> target_runner) {
135 base::Closure callback;
136 {
137 base::AutoLock auto_lock(lock_);
138
139 // If the target_runner has been updated, that implies an access to
140 // the class, so we can drop this request on the floor. (The
141 // alternative would be to forward it on to the new task runner.)
142 if (target_runner.get() != sink_task_runner_.get())
143 return;
144
145 if (sink_callback_.is_null())
146 return;
147
148 callback = sink_callback_;
149 }
150
151 // Run unlocked to allow caller to call back into us.
152 callback.Run();
153 }
154
155 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698