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

Side by Side Diff: webkit/glue/media/buffered_data_source.cc

Issue 164361: Refcounting BufferedResourceLoader (Closed)
Patch Set: done Created 11 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "base/compiler_specific.h" 5 #include "base/compiler_specific.h"
6 #include "base/message_loop.h" 6 #include "base/message_loop.h"
7 #include "base/process_util.h" 7 #include "base/process_util.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/common/extensions/url_pattern.h" 10 #include "chrome/common/extensions/url_pattern.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 offset_ = first_byte_position_; 115 offset_ = first_byte_position_;
116 } 116 }
117 117
118 // Creates the bridge on render thread since we can only access 118 // Creates the bridge on render thread since we can only access
119 // ResourceDispatcher on this thread. 119 // ResourceDispatcher on this thread.
120 bridge_.reset(bridge_factory_->CreateBridge(url_, 120 bridge_.reset(bridge_factory_->CreateBridge(url_,
121 net::LOAD_BYPASS_CACHE, 121 net::LOAD_BYPASS_CACHE,
122 first_byte_position_, 122 first_byte_position_,
123 last_byte_position_)); 123 last_byte_position_));
124 124
125 // Increment the reference count right before we start the request. This
126 // reference will be release when this request has ended.
127 AddRef();
128
125 // And start the resource loading. 129 // And start the resource loading.
126 bridge_->Start(this); 130 bridge_->Start(this);
127 } 131 }
128 132
129 void BufferedResourceLoader::Stop() { 133 void BufferedResourceLoader::Stop() {
130 // Reset callbacks. 134 // Reset callbacks.
131 start_callback_.reset(); 135 start_callback_.reset();
132 read_callback_.reset(); 136 read_callback_.reset();
133 137
134 // Destroy internal buffer. 138 // Destroy internal buffer.
135 buffer_.reset(); 139 buffer_.reset();
136 140
137 if (bridge_.get()) { 141 if (bridge_.get()) {
138 // Cancel the resource request. 142 // Cancel the request. This method call will cancel the request
143 // asynchronously. We may still get data or messages until we receive
144 // a response completed message.
145 if (deferred_)
146 bridge_->SetDefersLoading(false);
147 deferred_ = false;
139 bridge_->Cancel(); 148 bridge_->Cancel();
140 bridge_.reset();
141 } 149 }
142 } 150 }
143 151
144 void BufferedResourceLoader::Read(int64 position, 152 void BufferedResourceLoader::Read(int64 position,
145 int read_size, 153 int read_size,
146 uint8* buffer, 154 uint8* buffer,
147 net::CompletionCallback* read_callback) { 155 net::CompletionCallback* read_callback) {
148 DCHECK(!read_callback_.get()); 156 DCHECK(!read_callback_.get());
149 DCHECK(buffer_.get()); 157 DCHECK(buffer_.get());
150 DCHECK(read_callback); 158 DCHECK(read_callback);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 DoneRead(net::ERR_CACHE_MISS); 199 DoneRead(net::ERR_CACHE_MISS);
192 } 200 }
193 201
194 ///////////////////////////////////////////////////////////////////////////// 202 /////////////////////////////////////////////////////////////////////////////
195 // BufferedResourceLoader, 203 // BufferedResourceLoader,
196 // webkit_glue::ResourceLoaderBridge::Peer implementations 204 // webkit_glue::ResourceLoaderBridge::Peer implementations
197 bool BufferedResourceLoader::OnReceivedRedirect( 205 bool BufferedResourceLoader::OnReceivedRedirect(
198 const GURL& new_url, 206 const GURL& new_url,
199 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) { 207 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) {
200 DCHECK(bridge_.get()); 208 DCHECK(bridge_.get());
201 DCHECK(start_callback_.get());
202 209
203 // Saves the new URL. 210 // Saves the new URL.
204 url_ = new_url; 211 url_ = new_url;
205 212
213 // The load may have been stopped and |start_callback| is destroyed.
214 // In this case we shouldn't do anything.
215 if (!start_callback_.get())
216 return true;
217
206 // If we got redirected to an unsupported protocol then stop. 218 // If we got redirected to an unsupported protocol then stop.
207 if (!IsSchemeSupported(new_url)) { 219 if (!IsSchemeSupported(new_url)) {
208 DoneStart(net::ERR_ADDRESS_INVALID); 220 DoneStart(net::ERR_ADDRESS_INVALID);
209 Stop(); 221 Stop();
210 } 222 }
211 223
212 return true; 224 return true;
213 } 225 }
214 226
215 void BufferedResourceLoader::OnReceivedResponse( 227 void BufferedResourceLoader::OnReceivedResponse(
216 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, 228 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
217 bool content_filtered) { 229 bool content_filtered) {
218 DCHECK(bridge_.get()); 230 DCHECK(bridge_.get());
219 DCHECK(start_callback_.get()); 231
232 // The loader may have been stopped and |start_callback| is destroyed.
233 // In this case we shouldn't do anything.
234 if (!start_callback_.get())
235 return;
220 236
221 int64 first_byte_position = -1; 237 int64 first_byte_position = -1;
222 int64 last_byte_position = -1; 238 int64 last_byte_position = -1;
223 int64 instance_size = -1; 239 int64 instance_size = -1;
224 240
225 // The file:// protocol should be able to serve any request we want, so we 241 // The file:// protocol should be able to serve any request we want, so we
226 // take an exception for file protocol. 242 // take an exception for file protocol.
227 if (!url_.SchemeIsFile()) { 243 if (!url_.SchemeIsFile()) {
228 int error = net::OK; 244 int error = net::OK;
229 if (!info.headers) { 245 if (!info.headers) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // here. 277 // here.
262 if (first_byte_position != kPositionNotSpecified) 278 if (first_byte_position != kPositionNotSpecified)
263 offset_ = first_byte_position; 279 offset_ = first_byte_position;
264 280
265 // Calls with a successful response. 281 // Calls with a successful response.
266 DoneStart(net::OK); 282 DoneStart(net::OK);
267 } 283 }
268 284
269 void BufferedResourceLoader::OnReceivedData(const char* data, int len) { 285 void BufferedResourceLoader::OnReceivedData(const char* data, int len) {
270 DCHECK(bridge_.get()); 286 DCHECK(bridge_.get());
271 DCHECK(buffer_.get()); 287
288 // If this loader has been stopped, |buffer_| would be destroyed.
289 // In this case we shouldn't do anything.
290 if (!buffer_.get())
291 return;
272 292
273 // Writes more data to |buffer_|. 293 // Writes more data to |buffer_|.
274 buffer_->Append(len, reinterpret_cast<const uint8*>(data)); 294 buffer_->Append(len, reinterpret_cast<const uint8*>(data));
275 295
276 // If there is an active read request, try to fulfill the request. 296 // If there is an active read request, try to fulfill the request.
277 if (HasPendingRead() && CanFulfillRead()) { 297 if (HasPendingRead() && CanFulfillRead()) {
278 ReadInternal(); 298 ReadInternal();
279 } 299 }
280 300
281 // At last see if the buffer is full and we need to defer the downloading. 301 // At last see if the buffer is full and we need to defer the downloading.
282 EnableDeferIfNeeded(); 302 EnableDeferIfNeeded();
283 } 303 }
284 304
285 void BufferedResourceLoader::OnCompletedRequest( 305 void BufferedResourceLoader::OnCompletedRequest(
286 const URLRequestStatus& status, const std::string& security_info) { 306 const URLRequestStatus& status, const std::string& security_info) {
287 DCHECK(bridge_.get()); 307 DCHECK(bridge_.get());
288 DCHECK(buffer_.get());
289 308
290 // Saves the information that the request has completed. 309 // Saves the information that the request has completed.
291 completed_ = true; 310 completed_ = true;
292 311
293 // After the response has completed, we don't need the bridge any more.
294 bridge_.reset();
295
296 // If there is a start callback, calls it. 312 // If there is a start callback, calls it.
297 if (start_callback_.get()) { 313 if (start_callback_.get()) {
298 DoneStart(status.os_error()); 314 DoneStart(status.os_error());
299 } 315 }
300 316
301 // If there is a pending read but the request has ended, returns with what we 317 // If there is a pending read but the request has ended, returns with what
302 // have. 318 // we have.
303 if (HasPendingRead()) { 319 if (HasPendingRead()) {
304 // If the request has failed, then fail the read. 320 // Make sure we have a valid buffer before we satisfy a read request.
305 if (!status.is_success()) { 321 DCHECK(buffer_.get());
322
323 if (status.is_success()) {
324 // Try to fulfill with what is in the buffer.
325 if (CanFulfillRead())
326 ReadInternal();
327 else
328 DoneRead(net::ERR_CACHE_MISS);
329 } else {
330 // If the request has failed, then fail the read.
306 DoneRead(net::ERR_FAILED); 331 DoneRead(net::ERR_FAILED);
307 return;
308 } 332 }
309
310 // Otherwise try to fulfill with what is in the buffer.
311 if (CanFulfillRead())
312 ReadInternal();
313 else
314 DoneRead(net::ERR_CACHE_MISS);
315 } 333 }
316 334
317 // There must not be any outstanding read request. 335 // There must not be any outstanding read request.
318 DCHECK(!read_callback_.get()); 336 DCHECK(!HasPendingRead());
337
338 // We incremented the reference count when the loader was started. We balance
339 // that reference here so that we get destroyed. This is also the only safe
340 // place to destroy the ResourceLoaderBridge.
341 bridge_.reset();
342 Release();
319 } 343 }
320 344
321 ///////////////////////////////////////////////////////////////////////////// 345 /////////////////////////////////////////////////////////////////////////////
322 // BufferedResourceLoader, private 346 // BufferedResourceLoader, private
323 void BufferedResourceLoader::EnableDeferIfNeeded() { 347 void BufferedResourceLoader::EnableDeferIfNeeded() {
324 if (!deferred_ && 348 if (!deferred_ &&
325 buffer_->forward_bytes() >= buffer_->forward_capacity()) { 349 buffer_->forward_bytes() >= buffer_->forward_capacity()) {
326 deferred_ = true; 350 deferred_ = true;
327 351
328 if (bridge_.get()) 352 if (bridge_.get())
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 GetTimeoutMilliseconds() / 2, 574 GetTimeoutMilliseconds() / 2,
551 this, 575 this,
552 &BufferedDataSource::WatchDogTask); 576 &BufferedDataSource::WatchDogTask);
553 577
554 // Creates a new resource loader with the full range and a probe resource 578 // Creates a new resource loader with the full range and a probe resource
555 // loader. Creates a probe resource loader to make sure the server supports 579 // loader. Creates a probe resource loader to make sure the server supports
556 // partial range request. 580 // partial range request.
557 // TODO(hclam): Only request 1 byte for this probe request, it may be useful 581 // TODO(hclam): Only request 1 byte for this probe request, it may be useful
558 // that we perform a suffix range request and fetch the index. That way we 582 // that we perform a suffix range request and fetch the index. That way we
559 // can minimize the number of requests made. 583 // can minimize the number of requests made.
560 loader_.reset(CreateLoader(-1, -1)); 584 loader_ = CreateLoader(-1, -1);
561 probe_loader_.reset(CreateLoader(1, 1)); 585 probe_loader_ = CreateLoader(1, 1);
562 586
563 loader_->Start(NewCallback(this, &BufferedDataSource::InitialStartCallback)); 587 loader_->Start(NewCallback(this, &BufferedDataSource::InitialStartCallback));
564 probe_loader_->Start( 588 probe_loader_->Start(
565 NewCallback(this, &BufferedDataSource::ProbeStartCallback)); 589 NewCallback(this, &BufferedDataSource::ProbeStartCallback));
566 } 590 }
567 591
568 void BufferedDataSource::ReadTask( 592 void BufferedDataSource::ReadTask(
569 int64 position, int read_size, uint8* buffer, 593 int64 position, int read_size, uint8* buffer,
570 media::DataSource::ReadCallback* read_callback) { 594 media::DataSource::ReadCallback* read_callback) {
571 DCHECK(MessageLoop::current() == render_loop_); 595 DCHECK(MessageLoop::current() == render_loop_);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 read_position_ = 0; 635 read_position_ = 0;
612 read_size_ = 0; 636 read_size_ = 0;
613 read_buffer_ = 0; 637 read_buffer_ = 0;
614 read_submitted_time_ = base::Time(); 638 read_submitted_time_ = base::Time();
615 read_attempts_ = 0; 639 read_attempts_ = 0;
616 640
617 // Signal that stop task has finished execution. 641 // Signal that stop task has finished execution.
618 stop_task_finished_ = true; 642 stop_task_finished_ = true;
619 } 643 }
620 644
621 void BufferedDataSource::SwapLoaderTask(BufferedResourceLoader* loader) { 645 void BufferedDataSource::SwapLoaderTask(
646 scoped_refptr<BufferedResourceLoader> loader) {
622 DCHECK(MessageLoop::current() == render_loop_); 647 DCHECK(MessageLoop::current() == render_loop_);
623 DCHECK(loader); 648 DCHECK(loader);
624 649
625 loader_.reset(loader); 650 loader_ = loader;
626 loader_->Start(NewCallback(this, 651 loader_->Start(NewCallback(this,
627 &BufferedDataSource::PartialReadStartCallback)); 652 &BufferedDataSource::PartialReadStartCallback));
628 } 653 }
629 654
630 void BufferedDataSource::WatchDogTask() { 655 void BufferedDataSource::WatchDogTask() {
631 DCHECK(MessageLoop::current() == render_loop_); 656 DCHECK(MessageLoop::current() == render_loop_);
632 657
633 // We only care if there is an active read request. 658 // We only care if there is an active read request.
634 if (!read_callback_.get()) 659 if (!read_callback_.get())
635 return; 660 return;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 render_loop_->PostTask(FROM_HERE, 861 render_loop_->PostTask(FROM_HERE,
837 NewRunnableMethod(this, &BufferedDataSource::SwapLoaderTask, 862 NewRunnableMethod(this, &BufferedDataSource::SwapLoaderTask,
838 CreateLoader(read_position_, -1))); 863 CreateLoader(read_position_, -1)));
839 } else { 864 } else {
840 loader_->Stop(); 865 loader_->Stop();
841 DoneRead(error); 866 DoneRead(error);
842 } 867 }
843 } 868 }
844 869
845 } // namespace webkit_glue 870 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/media/buffered_data_source.h ('k') | webkit/glue/media/buffered_data_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698