Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 read_position_(0), | 91 read_position_(0), |
| 92 read_size_(0), | 92 read_size_(0), |
| 93 read_buffer_(NULL), | 93 read_buffer_(NULL), |
| 94 first_offset_(0), | 94 first_offset_(0), |
| 95 last_offset_(0) { | 95 last_offset_(0) { |
| 96 } | 96 } |
| 97 | 97 |
| 98 BufferedResourceLoader::~BufferedResourceLoader() { | 98 BufferedResourceLoader::~BufferedResourceLoader() { |
| 99 } | 99 } |
| 100 | 100 |
| 101 void BufferedResourceLoader::Start(net::CompletionCallback* start_callback) { | 101 void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, |
| 102 Callback0::Type* event_callback) { | |
|
scherkus (not reviewing)
2009/10/15 23:51:38
use NetworkEventCallback instead
| |
| 102 // Make sure we have not started. | 103 // Make sure we have not started. |
| 103 DCHECK(!bridge_.get()); | 104 DCHECK(!bridge_.get()); |
| 104 DCHECK(!start_callback_.get()); | 105 DCHECK(!start_callback_.get()); |
| 106 DCHECK(!event_callback_.get()); | |
| 105 DCHECK(start_callback); | 107 DCHECK(start_callback); |
| 108 DCHECK(event_callback); | |
| 106 | 109 |
| 107 start_callback_.reset(start_callback); | 110 start_callback_.reset(start_callback); |
| 111 event_callback_.reset(event_callback); | |
| 108 | 112 |
| 109 if (first_byte_position_ != kPositionNotSpecified) { | 113 if (first_byte_position_ != kPositionNotSpecified) { |
| 110 range_requested_ = true; | 114 range_requested_ = true; |
| 111 // TODO(hclam): server may not support range request so |offset_| may not | 115 // TODO(hclam): server may not support range request so |offset_| may not |
| 112 // equal to |first_byte_position_|. | 116 // equal to |first_byte_position_|. |
| 113 offset_ = first_byte_position_; | 117 offset_ = first_byte_position_; |
| 114 } | 118 } |
| 115 | 119 |
| 116 // Creates the bridge on render thread since we can only access | 120 // Creates the bridge on render thread since we can only access |
| 117 // ResourceDispatcher on this thread. | 121 // ResourceDispatcher on this thread. |
| 118 bridge_.reset( | 122 bridge_.reset( |
| 119 bridge_factory_->CreateBridge( | 123 bridge_factory_->CreateBridge( |
| 120 url_, | 124 url_, |
| 121 IsMediaCacheEnabled() ? net::LOAD_NORMAL : net::LOAD_BYPASS_CACHE, | 125 IsMediaCacheEnabled() ? net::LOAD_NORMAL : net::LOAD_BYPASS_CACHE, |
| 122 first_byte_position_, | 126 first_byte_position_, |
| 123 last_byte_position_)); | 127 last_byte_position_)); |
| 124 | 128 |
| 125 // Increment the reference count right before we start the request. This | 129 // Increment the reference count right before we start the request. This |
| 126 // reference will be release when this request has ended. | 130 // reference will be release when this request has ended. |
| 127 AddRef(); | 131 AddRef(); |
| 128 | 132 |
| 129 // And start the resource loading. | 133 // And start the resource loading. |
| 130 bridge_->Start(this); | 134 bridge_->Start(this); |
| 131 } | 135 } |
| 132 | 136 |
| 133 void BufferedResourceLoader::Stop() { | 137 void BufferedResourceLoader::Stop() { |
| 134 // Reset callbacks. | 138 // Reset callbacks. |
| 135 start_callback_.reset(); | 139 start_callback_.reset(); |
| 140 event_callback_.reset(); | |
| 136 read_callback_.reset(); | 141 read_callback_.reset(); |
| 137 | 142 |
| 143 // Use the internal buffer to signal that we have been stopped. | |
| 144 // TODO(hclam): Not so pretty to do this. | |
| 145 if (!buffer_.get()) | |
| 146 return; | |
| 147 | |
| 138 // Destroy internal buffer. | 148 // Destroy internal buffer. |
| 139 buffer_.reset(); | 149 buffer_.reset(); |
| 140 | 150 |
| 141 if (bridge_.get()) { | 151 if (bridge_.get()) { |
| 142 // Cancel the request. This method call will cancel the request | 152 // Cancel the request. This method call will cancel the request |
| 143 // asynchronously. We may still get data or messages until we receive | 153 // asynchronously. We may still get data or messages until we receive |
| 144 // a response completed message. | 154 // a response completed message. |
| 145 if (deferred_) | 155 if (deferred_) |
| 146 bridge_->SetDefersLoading(false); | 156 bridge_->SetDefersLoading(false); |
| 147 deferred_ = false; | 157 deferred_ = false; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 | 202 |
| 193 // If we expected the read request to be fulfilled later, returns | 203 // If we expected the read request to be fulfilled later, returns |
| 194 // immediately and let more data to flow in. | 204 // immediately and let more data to flow in. |
| 195 if (WillFulfillRead()) | 205 if (WillFulfillRead()) |
| 196 return; | 206 return; |
| 197 | 207 |
| 198 // Make a callback to report failure. | 208 // Make a callback to report failure. |
| 199 DoneRead(net::ERR_CACHE_MISS); | 209 DoneRead(net::ERR_CACHE_MISS); |
| 200 } | 210 } |
| 201 | 211 |
| 212 int64 BufferedResourceLoader::GetBufferedFirstBytePosition() { | |
| 213 if (buffer_.get()) | |
| 214 return offset_ - static_cast<int>(buffer_->backward_bytes()); | |
| 215 return kPositionNotSpecified; | |
| 216 } | |
| 217 | |
| 218 int64 BufferedResourceLoader::GetBufferedLastBytePosition() { | |
| 219 if (buffer_.get()) | |
| 220 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; | |
| 221 return kPositionNotSpecified; | |
| 222 } | |
| 223 | |
| 202 ///////////////////////////////////////////////////////////////////////////// | 224 ///////////////////////////////////////////////////////////////////////////// |
| 203 // BufferedResourceLoader, | 225 // BufferedResourceLoader, |
| 204 // webkit_glue::ResourceLoaderBridge::Peer implementations | 226 // webkit_glue::ResourceLoaderBridge::Peer implementations |
| 205 bool BufferedResourceLoader::OnReceivedRedirect( | 227 bool BufferedResourceLoader::OnReceivedRedirect( |
| 206 const GURL& new_url, | 228 const GURL& new_url, |
| 207 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) { | 229 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) { |
| 208 DCHECK(bridge_.get()); | 230 DCHECK(bridge_.get()); |
| 209 | 231 |
| 210 // Save the new URL. | 232 // Save the new URL. |
| 211 url_ = new_url; | 233 url_ = new_url; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 // Writes more data to |buffer_|. | 315 // Writes more data to |buffer_|. |
| 294 buffer_->Append(len, reinterpret_cast<const uint8*>(data)); | 316 buffer_->Append(len, reinterpret_cast<const uint8*>(data)); |
| 295 | 317 |
| 296 // If there is an active read request, try to fulfill the request. | 318 // If there is an active read request, try to fulfill the request. |
| 297 if (HasPendingRead() && CanFulfillRead()) { | 319 if (HasPendingRead() && CanFulfillRead()) { |
| 298 ReadInternal(); | 320 ReadInternal(); |
| 299 } | 321 } |
| 300 | 322 |
| 301 // At last see if the buffer is full and we need to defer the downloading. | 323 // At last see if the buffer is full and we need to defer the downloading. |
| 302 EnableDeferIfNeeded(); | 324 EnableDeferIfNeeded(); |
| 325 | |
| 326 // Notify that we have received some data. | |
| 327 NotifyNetworkEvent(); | |
| 303 } | 328 } |
| 304 | 329 |
| 305 void BufferedResourceLoader::OnCompletedRequest( | 330 void BufferedResourceLoader::OnCompletedRequest( |
| 306 const URLRequestStatus& status, const std::string& security_info) { | 331 const URLRequestStatus& status, const std::string& security_info) { |
| 307 DCHECK(bridge_.get()); | 332 DCHECK(bridge_.get()); |
| 308 | 333 |
| 309 // Saves the information that the request has completed. | 334 // Saves the information that the request has completed. |
| 310 completed_ = true; | 335 completed_ = true; |
| 311 | 336 |
| 312 // If there is a start callback, calls it. | 337 // If there is a start callback, calls it. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 328 DoneRead(net::ERR_CACHE_MISS); | 353 DoneRead(net::ERR_CACHE_MISS); |
| 329 } else { | 354 } else { |
| 330 // If the request has failed, then fail the read. | 355 // If the request has failed, then fail the read. |
| 331 DoneRead(net::ERR_FAILED); | 356 DoneRead(net::ERR_FAILED); |
| 332 } | 357 } |
| 333 } | 358 } |
| 334 | 359 |
| 335 // There must not be any outstanding read request. | 360 // There must not be any outstanding read request. |
| 336 DCHECK(!HasPendingRead()); | 361 DCHECK(!HasPendingRead()); |
| 337 | 362 |
| 363 // Notify that network response is completed. | |
| 364 NotifyNetworkEvent(); | |
| 365 | |
| 338 // We incremented the reference count when the loader was started. We balance | 366 // 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 | 367 // that reference here so that we get destroyed. This is also the only safe |
| 340 // place to destroy the ResourceLoaderBridge. | 368 // place to destroy the ResourceLoaderBridge. |
| 341 bridge_.reset(); | 369 bridge_.reset(); |
| 342 Release(); | 370 Release(); |
| 343 } | 371 } |
| 344 | 372 |
| 345 ///////////////////////////////////////////////////////////////////////////// | 373 ///////////////////////////////////////////////////////////////////////////// |
| 346 // BufferedResourceLoader, private | 374 // BufferedResourceLoader, private |
| 347 void BufferedResourceLoader::EnableDeferIfNeeded() { | 375 void BufferedResourceLoader::EnableDeferIfNeeded() { |
| 348 if (!deferred_ && | 376 if (!deferred_ && |
| 349 buffer_->forward_bytes() >= buffer_->forward_capacity()) { | 377 buffer_->forward_bytes() >= buffer_->forward_capacity()) { |
| 350 deferred_ = true; | 378 deferred_ = true; |
| 351 | 379 |
| 352 if (bridge_.get()) | 380 if (bridge_.get()) |
| 353 bridge_->SetDefersLoading(true); | 381 bridge_->SetDefersLoading(true); |
| 382 | |
| 383 NotifyNetworkEvent(); | |
| 354 } | 384 } |
| 355 } | 385 } |
| 356 | 386 |
| 357 void BufferedResourceLoader::DisableDeferIfNeeded() { | 387 void BufferedResourceLoader::DisableDeferIfNeeded() { |
| 358 if (deferred_ && | 388 if (deferred_ && |
| 359 buffer_->forward_bytes() < buffer_->forward_capacity() / 2) { | 389 buffer_->forward_bytes() < buffer_->forward_capacity() / 2) { |
| 360 deferred_ = false; | 390 deferred_ = false; |
| 361 | 391 |
| 362 if (bridge_.get()) | 392 if (bridge_.get()) |
| 363 bridge_->SetDefersLoading(false); | 393 bridge_->SetDefersLoading(false); |
| 394 | |
| 395 NotifyNetworkEvent(); | |
| 364 } | 396 } |
| 365 } | 397 } |
| 366 | 398 |
| 367 bool BufferedResourceLoader::CanFulfillRead() { | 399 bool BufferedResourceLoader::CanFulfillRead() { |
| 368 // If we are reading too far in the backward direction. | 400 // If we are reading too far in the backward direction. |
| 369 if (first_offset_ < 0 && | 401 if (first_offset_ < 0 && |
| 370 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) | 402 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) |
| 371 return false; | 403 return false; |
| 372 | 404 |
| 373 // If the start offset is too far ahead. | 405 // If the start offset is too far ahead. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 DCHECK(ret); | 443 DCHECK(ret); |
| 412 | 444 |
| 413 // Then do the read. | 445 // Then do the read. |
| 414 int read = static_cast<int>(buffer_->Read(read_size_, read_buffer_)); | 446 int read = static_cast<int>(buffer_->Read(read_size_, read_buffer_)); |
| 415 offset_ += first_offset_ + read; | 447 offset_ += first_offset_ + read; |
| 416 | 448 |
| 417 // And report with what we have read. | 449 // And report with what we have read. |
| 418 DoneRead(read); | 450 DoneRead(read); |
| 419 } | 451 } |
| 420 | 452 |
| 421 void BufferedResourceLoader::DoneRead(int error) { | |
| 422 read_callback_->RunWithParams(Tuple1<int>(error)); | |
| 423 read_callback_.reset(); | |
| 424 read_position_ = 0; | |
| 425 read_size_ = 0; | |
| 426 read_buffer_ = NULL; | |
| 427 first_offset_ = 0; | |
| 428 last_offset_ = 0; | |
| 429 } | |
| 430 | |
| 431 void BufferedResourceLoader::DoneStart(int error) { | |
| 432 start_callback_->RunWithParams(Tuple1<int>(error)); | |
| 433 start_callback_.reset(); | |
| 434 } | |
| 435 | |
| 436 bool BufferedResourceLoader::VerifyPartialResponse( | 453 bool BufferedResourceLoader::VerifyPartialResponse( |
| 437 const ResourceLoaderBridge::ResponseInfo& info) { | 454 const ResourceLoaderBridge::ResponseInfo& info) { |
| 438 int64 first_byte_position, last_byte_position, instance_size; | 455 int64 first_byte_position, last_byte_position, instance_size; |
| 439 if (!info.headers->GetContentRange(&first_byte_position, | 456 if (!info.headers->GetContentRange(&first_byte_position, |
| 440 &last_byte_position, | 457 &last_byte_position, |
| 441 &instance_size)) { | 458 &instance_size)) { |
| 442 return false; | 459 return false; |
| 443 } | 460 } |
| 444 | 461 |
| 445 if (instance_size != kPositionNotSpecified) | 462 if (instance_size != kPositionNotSpecified) |
| 446 instance_size_ = instance_size; | 463 instance_size_ = instance_size; |
| 447 | 464 |
| 448 if (first_byte_position_ != -1 && | 465 if (first_byte_position_ != -1 && |
| 449 first_byte_position_ != first_byte_position) { | 466 first_byte_position_ != first_byte_position) { |
| 450 return false; | 467 return false; |
| 451 } | 468 } |
| 452 | 469 |
| 453 // TODO(hclam): I should also check |last_byte_position|, but since | 470 // TODO(hclam): I should also check |last_byte_position|, but since |
| 454 // we will never make such a request that it is ok to leave it unimplemented. | 471 // we will never make such a request that it is ok to leave it unimplemented. |
| 455 return true; | 472 return true; |
| 456 } | 473 } |
| 457 | 474 |
| 458 ////////////////////////////////////////////////////////////////////////////// | 475 void BufferedResourceLoader::DoneRead(int error) { |
| 476 read_callback_->RunWithParams(Tuple1<int>(error)); | |
| 477 read_callback_.reset(); | |
| 478 read_position_ = 0; | |
| 479 read_size_ = 0; | |
| 480 read_buffer_ = NULL; | |
| 481 first_offset_ = 0; | |
| 482 last_offset_ = 0; | |
| 483 } | |
| 484 | |
| 485 void BufferedResourceLoader::DoneStart(int error) { | |
| 486 start_callback_->RunWithParams(Tuple1<int>(error)); | |
| 487 start_callback_.reset(); | |
| 488 } | |
| 489 | |
| 490 void BufferedResourceLoader::NotifyNetworkEvent() { | |
| 491 if (event_callback_.get()) | |
| 492 event_callback_->Run(); | |
| 493 } | |
| 494 | |
| 495 ///////////////////////////////////////////////////////////////////////////// | |
| 459 // BufferedDataSource, protected | 496 // BufferedDataSource, protected |
| 460 BufferedDataSource::BufferedDataSource( | 497 BufferedDataSource::BufferedDataSource( |
| 461 MessageLoop* render_loop, | 498 MessageLoop* render_loop, |
| 462 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) | 499 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) |
| 463 : total_bytes_(kPositionNotSpecified), | 500 : total_bytes_(kPositionNotSpecified), |
| 501 loaded_(false), | |
| 464 streaming_(false), | 502 streaming_(false), |
| 465 bridge_factory_(bridge_factory), | 503 bridge_factory_(bridge_factory), |
| 466 loader_(NULL), | 504 loader_(NULL), |
| 505 network_activity_(false), | |
| 467 initialize_callback_(NULL), | 506 initialize_callback_(NULL), |
| 468 read_callback_(NULL), | 507 read_callback_(NULL), |
| 469 read_position_(0), | 508 read_position_(0), |
| 470 read_size_(0), | 509 read_size_(0), |
| 471 read_buffer_(NULL), | 510 read_buffer_(NULL), |
| 472 read_attempts_(0), | 511 read_attempts_(0), |
| 473 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), | 512 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), |
| 474 intermediate_read_buffer_size_(kInitialReadBufferSize), | 513 intermediate_read_buffer_size_(kInitialReadBufferSize), |
| 475 render_loop_(render_loop), | 514 render_loop_(render_loop), |
| 476 stopped_(false), | 515 stop_signal_received_(false), |
| 477 stop_task_finished_(false) { | 516 stopped_on_render_loop_(false) { |
| 478 } | 517 } |
| 479 | 518 |
| 480 BufferedDataSource::~BufferedDataSource() { | 519 BufferedDataSource::~BufferedDataSource() { |
| 481 } | 520 } |
| 482 | 521 |
| 483 // A factory method to create BufferedResourceLoader using the read parameters. | 522 // A factory method to create BufferedResourceLoader using the read parameters. |
| 484 // This method can be overrided to inject mock BufferedResourceLoader object | 523 // This method can be overrided to inject mock BufferedResourceLoader object |
| 485 // for testing purpose. | 524 // for testing purpose. |
| 486 BufferedResourceLoader* BufferedDataSource::CreateLoader( | 525 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( |
| 487 int64 first_byte_position, int64 last_byte_position) { | 526 int64 first_byte_position, int64 last_byte_position) { |
| 488 DCHECK(MessageLoop::current() == render_loop_); | 527 DCHECK(MessageLoop::current() == render_loop_); |
| 489 | 528 |
| 490 return new BufferedResourceLoader(bridge_factory_.get(), url_, | 529 return new BufferedResourceLoader(bridge_factory_.get(), url_, |
| 491 first_byte_position, | 530 first_byte_position, |
| 492 last_byte_position); | 531 last_byte_position); |
| 493 } | 532 } |
| 494 | 533 |
| 495 // This method simply returns kTimeoutMilliseconds. The purpose of this | 534 // This method simply returns kTimeoutMilliseconds. The purpose of this |
| 496 // method is to be overidded so as to provide a different timeout value | 535 // method is to be overidded so as to provide a different timeout value |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 523 media_format_.SetAsString(media::MediaFormat::kURL, url); | 562 media_format_.SetAsString(media::MediaFormat::kURL, url); |
| 524 | 563 |
| 525 // Post a task to complete the initialization task. | 564 // Post a task to complete the initialization task. |
| 526 render_loop_->PostTask(FROM_HERE, | 565 render_loop_->PostTask(FROM_HERE, |
| 527 NewRunnableMethod(this, &BufferedDataSource::InitializeTask)); | 566 NewRunnableMethod(this, &BufferedDataSource::InitializeTask)); |
| 528 } | 567 } |
| 529 | 568 |
| 530 void BufferedDataSource::Stop() { | 569 void BufferedDataSource::Stop() { |
| 531 { | 570 { |
| 532 AutoLock auto_lock(lock_); | 571 AutoLock auto_lock(lock_); |
| 533 stopped_ = true; | 572 stop_signal_received_ = true; |
| 534 } | 573 } |
| 535 render_loop_->PostTask(FROM_HERE, | 574 render_loop_->PostTask(FROM_HERE, |
| 536 NewRunnableMethod(this, &BufferedDataSource::StopTask)); | 575 NewRunnableMethod(this, &BufferedDataSource::StopTask)); |
| 537 } | 576 } |
| 538 | 577 |
| 539 ///////////////////////////////////////////////////////////////////////////// | 578 ///////////////////////////////////////////////////////////////////////////// |
| 540 // BufferedDataSource, media::DataSource implementation | 579 // BufferedDataSource, media::DataSource implementation |
| 541 void BufferedDataSource::Read(int64 position, size_t size, | 580 void BufferedDataSource::Read(int64 position, size_t size, uint8* data, |
| 542 uint8* data, | |
| 543 media::DataSource::ReadCallback* read_callback) { | 581 media::DataSource::ReadCallback* read_callback) { |
| 544 render_loop_->PostTask(FROM_HERE, | 582 render_loop_->PostTask(FROM_HERE, |
| 545 NewRunnableMethod(this, &BufferedDataSource::ReadTask, | 583 NewRunnableMethod(this, &BufferedDataSource::ReadTask, |
| 546 position, static_cast<int>(size), data, read_callback)); | 584 position, static_cast<int>(size), data, read_callback)); |
| 547 } | 585 } |
| 548 | 586 |
| 549 bool BufferedDataSource::GetSize(int64* size_out) { | 587 bool BufferedDataSource::GetSize(int64* size_out) { |
| 550 if (total_bytes_ != kPositionNotSpecified) { | 588 if (total_bytes_ != kPositionNotSpecified) { |
| 551 *size_out = total_bytes_; | 589 *size_out = total_bytes_; |
| 552 return true; | 590 return true; |
| 553 } | 591 } |
| 554 *size_out = 0; | 592 *size_out = 0; |
| 555 return false; | 593 return false; |
| 556 } | 594 } |
| 557 | 595 |
| 558 bool BufferedDataSource::IsStreaming() { | 596 bool BufferedDataSource::IsStreaming() { |
| 559 return streaming_; | 597 return streaming_; |
| 560 } | 598 } |
| 561 | 599 |
| 562 ///////////////////////////////////////////////////////////////////////////// | 600 ///////////////////////////////////////////////////////////////////////////// |
| 563 // BufferedDataSource, render thread tasks | 601 // BufferedDataSource, render thread tasks |
| 564 void BufferedDataSource::InitializeTask() { | 602 void BufferedDataSource::InitializeTask() { |
| 565 DCHECK(MessageLoop::current() == render_loop_); | 603 DCHECK(MessageLoop::current() == render_loop_); |
| 566 DCHECK(!loader_.get()); | 604 DCHECK(!loader_.get()); |
| 605 DCHECK(!stopped_on_render_loop_); | |
| 567 | 606 |
| 568 // Kick starts the watch dog task that will handle connection timeout. | 607 // Kick starts the watch dog task that will handle connection timeout. |
| 569 // We run the watch dog 2 times faster the actual timeout so as to catch | 608 // We run the watch dog 2 times faster the actual timeout so as to catch |
| 570 // the timeout more accurately. | 609 // the timeout more accurately. |
| 571 watch_dog_timer_.Start( | 610 watch_dog_timer_.Start( |
| 572 GetTimeoutMilliseconds() / 2, | 611 GetTimeoutMilliseconds() / 2, |
| 573 this, | 612 this, |
| 574 &BufferedDataSource::WatchDogTask); | 613 &BufferedDataSource::WatchDogTask); |
| 575 | 614 |
| 576 if (IsHttpProtocol(url_)) { | 615 if (IsHttpProtocol(url_)) { |
| 577 // Fetch only first 1024 bytes as this usually covers the header portion | 616 // Fetch only first 1024 bytes as this usually covers the header portion |
| 578 // of a media file that gives enough information about the codecs, etc. | 617 // of a media file that gives enough information about the codecs, etc. |
| 579 // This also serve as a probe to determine server capability to serve | 618 // This also serve as a probe to determine server capability to serve |
| 580 // range request. | 619 // range request. |
| 581 // TODO(hclam): Do some experiments for the best approach. | 620 // TODO(hclam): Do some experiments for the best approach. |
| 582 loader_ = CreateLoader(0, 1024); | 621 loader_ = CreateResourceLoader(0, 1024); |
| 583 loader_->Start( | 622 loader_->Start( |
| 584 NewCallback(this, | 623 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), |
| 585 &BufferedDataSource::HttpInitialStartCallback)); | 624 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); |
| 586 } else { | 625 } else { |
| 587 // For all other protocols, assume they support range request. We fetch | 626 // For all other protocols, assume they support range request. We fetch |
| 588 // the full range of the resource to obtain the instance size because | 627 // the full range of the resource to obtain the instance size because |
| 589 // we won't be served HTTP headers. | 628 // we won't be served HTTP headers. |
| 590 loader_ = CreateLoader(-1, -1); | 629 loader_ = CreateResourceLoader(-1, -1); |
| 591 loader_->Start( | 630 loader_->Start( |
| 592 NewCallback(this, | 631 NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback), |
| 593 &BufferedDataSource::NonHttpInitialStartCallback)); | 632 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); |
| 594 } | 633 } |
| 595 } | 634 } |
| 596 | 635 |
| 597 void BufferedDataSource::ReadTask( | 636 void BufferedDataSource::ReadTask( |
| 598 int64 position, int read_size, uint8* buffer, | 637 int64 position, int read_size, uint8* buffer, |
| 599 media::DataSource::ReadCallback* read_callback) { | 638 media::DataSource::ReadCallback* read_callback) { |
| 600 DCHECK(MessageLoop::current() == render_loop_); | 639 DCHECK(MessageLoop::current() == render_loop_); |
| 601 | 640 |
| 602 // If StopTask() was executed we should return immediately. We check this | 641 // If StopTask() was executed we should return immediately. We check this |
| 603 // variable to prevent doing any actual work after clean up was done. We do | 642 // variable to prevent doing any actual work after clean up was done. We do |
| 604 // not check |stopped_| because anything use of it has to be within |lock_| | 643 // not check |stop_signal_received_| because anything use of it has to be |
| 605 // which is not desirable. | 644 // within |lock_| which is not desirable. |
| 606 if (stop_task_finished_) | 645 if (stopped_on_render_loop_) |
| 607 return; | 646 return; |
| 608 | 647 |
| 609 DCHECK(!read_callback_.get()); | 648 DCHECK(!read_callback_.get()); |
| 610 DCHECK(read_callback); | 649 DCHECK(read_callback); |
| 611 | 650 |
| 612 // Saves the read parameters. | 651 // Saves the read parameters. |
| 613 read_position_ = position; | 652 read_position_ = position; |
| 614 read_size_ = read_size; | 653 read_size_ = read_size; |
| 615 read_callback_.reset(read_callback); | 654 read_callback_.reset(read_callback); |
| 616 read_buffer_ = buffer; | 655 read_buffer_ = buffer; |
| 617 read_submitted_time_ = base::Time::Now(); | 656 read_submitted_time_ = base::Time::Now(); |
| 618 read_attempts_ = 0; | 657 read_attempts_ = 0; |
| 619 | 658 |
| 620 // Call to read internal to perform the actual read. | 659 // Call to read internal to perform the actual read. |
| 621 ReadInternal(); | 660 ReadInternal(); |
| 622 } | 661 } |
| 623 | 662 |
| 624 void BufferedDataSource::StopTask() { | 663 void BufferedDataSource::StopTask() { |
| 625 DCHECK(MessageLoop::current() == render_loop_); | 664 DCHECK(MessageLoop::current() == render_loop_); |
| 665 DCHECK(!stopped_on_render_loop_); | |
| 626 | 666 |
| 627 // Stop the watch dog. | 667 // Stop the watch dog. |
| 628 watch_dog_timer_.Stop(); | 668 watch_dog_timer_.Stop(); |
| 629 | 669 |
| 630 // We just need to stop the loader, so it stops activity. | 670 // We just need to stop the loader, so it stops activity. |
| 631 if (loader_.get()) | 671 if (loader_.get()) |
| 632 loader_->Stop(); | 672 loader_->Stop(); |
| 633 | 673 |
| 634 // Reset the parameters of the current read request. | 674 // Reset the parameters of the current read request. |
| 635 read_callback_.reset(); | 675 read_callback_.reset(); |
| 636 read_position_ = 0; | 676 read_position_ = 0; |
| 637 read_size_ = 0; | 677 read_size_ = 0; |
| 638 read_buffer_ = 0; | 678 read_buffer_ = 0; |
| 639 read_submitted_time_ = base::Time(); | 679 read_submitted_time_ = base::Time(); |
| 640 read_attempts_ = 0; | 680 read_attempts_ = 0; |
| 641 | 681 |
| 642 // Signal that stop task has finished execution. | 682 // Signal that stop task has finished execution. |
| 643 stop_task_finished_ = true; | 683 stopped_on_render_loop_ = true; |
| 644 } | 684 } |
| 645 | 685 |
| 646 void BufferedDataSource::SwapLoaderTask( | 686 void BufferedDataSource::RestartLoadingTask() { |
| 647 scoped_refptr<BufferedResourceLoader> loader) { | |
| 648 DCHECK(MessageLoop::current() == render_loop_); | 687 DCHECK(MessageLoop::current() == render_loop_); |
| 649 DCHECK(loader); | |
| 650 | 688 |
| 651 loader_ = loader; | 689 // This variable is set in StopTask(). We check this and do an early return. |
| 652 loader_->Start(NewCallback(this, | 690 // The sequence of actions which enable this conditions is: |
| 653 &BufferedDataSource::PartialReadStartCallback)); | 691 // 1. Stop() is called from the pipeline. |
| 692 // 2. ReadCallback() is called from the resource loader. | |
| 693 // 3. StopTask() is executed. | |
| 694 // 4. RestartLoadingTask() is executed. | |
| 695 if (stopped_on_render_loop_) | |
| 696 return; | |
| 697 | |
| 698 // If there's no outstanding read then return early. | |
| 699 if (!read_callback_.get()) | |
| 700 return; | |
| 701 | |
| 702 loader_ = CreateResourceLoader(read_position_, -1); | |
| 703 loader_->Start( | |
| 704 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), | |
| 705 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); | |
| 654 } | 706 } |
| 655 | 707 |
| 656 void BufferedDataSource::WatchDogTask() { | 708 void BufferedDataSource::WatchDogTask() { |
| 657 DCHECK(MessageLoop::current() == render_loop_); | 709 DCHECK(MessageLoop::current() == render_loop_); |
| 710 DCHECK(!stopped_on_render_loop_); | |
| 658 | 711 |
| 659 // We only care if there is an active read request. | 712 // We only care if there is an active read request. |
| 660 if (!read_callback_.get()) | 713 if (!read_callback_.get()) |
| 661 return; | 714 return; |
| 662 | 715 |
| 663 DCHECK(loader_.get()); | 716 DCHECK(loader_.get()); |
| 664 base::TimeDelta delta = base::Time::Now() - read_submitted_time_; | 717 base::TimeDelta delta = base::Time::Now() - read_submitted_time_; |
| 665 if (delta < GetTimeoutMilliseconds()) | 718 if (delta < GetTimeoutMilliseconds()) |
| 666 return; | 719 return; |
| 667 | 720 |
| 668 // TODO(hclam): Maybe raise an error here. But if an error is reported | 721 // TODO(hclam): Maybe raise an error here. But if an error is reported |
| 669 // the whole pipeline may get destroyed... | 722 // the whole pipeline may get destroyed... |
| 670 if (read_attempts_ >= kReadTrials) | 723 if (read_attempts_ >= kReadTrials) |
| 671 return; | 724 return; |
| 672 | 725 |
| 673 ++read_attempts_; | 726 ++read_attempts_; |
| 674 read_submitted_time_ = base::Time::Now(); | 727 read_submitted_time_ = base::Time::Now(); |
| 675 | 728 |
| 676 // Stops the current loader and swap in a new resource loader and | 729 // Stops the current loader and creates a new resource loader and |
| 677 // retry the request. | 730 // retry the request. |
| 678 loader_->Stop(); | 731 loader_->Stop(); |
| 679 SwapLoaderTask(CreateLoader(read_position_, -1)); | 732 loader_ = CreateResourceLoader(read_position_, -1); |
| 733 loader_->Start( | |
| 734 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), | |
| 735 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); | |
| 680 } | 736 } |
| 681 | 737 |
| 682 // This method is the place where actual read happens, |loader_| must be valid | 738 // This method is the place where actual read happens, |loader_| must be valid |
| 683 // prior to make this method call. | 739 // prior to make this method call. |
| 684 void BufferedDataSource::ReadInternal() { | 740 void BufferedDataSource::ReadInternal() { |
| 685 DCHECK(MessageLoop::current() == render_loop_); | 741 DCHECK(MessageLoop::current() == render_loop_); |
| 686 DCHECK(loader_.get()); | 742 DCHECK(loader_.get()); |
| 687 | 743 |
| 688 // First we prepare the intermediate read buffer for BufferedResourceLoader | 744 // First we prepare the intermediate read buffer for BufferedResourceLoader |
| 689 // to write to. | 745 // to write to. |
| 690 if (read_size_ > intermediate_read_buffer_size_) { | 746 if (read_size_ > intermediate_read_buffer_size_) { |
| 691 intermediate_read_buffer_.reset(new uint8[read_size_]); | 747 intermediate_read_buffer_.reset(new uint8[read_size_]); |
| 692 } | 748 } |
| 693 | 749 |
| 694 // Perform the actual read with BufferedResourceLoader. | 750 // Perform the actual read with BufferedResourceLoader. |
| 695 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(), | 751 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(), |
| 696 NewCallback(this, &BufferedDataSource::ReadCallback)); | 752 NewCallback(this, &BufferedDataSource::ReadCallback)); |
| 697 } | 753 } |
| 698 | 754 |
| 699 // Method to report the results of the current read request. Also reset all | 755 // Method to report the results of the current read request. Also reset all |
| 700 // the read parameters. | 756 // the read parameters. |
| 701 void BufferedDataSource::DoneRead(int error) { | 757 void BufferedDataSource::DoneRead_Locked(int error) { |
| 702 DCHECK(MessageLoop::current() == render_loop_); | 758 DCHECK(MessageLoop::current() == render_loop_); |
| 759 DCHECK(read_callback_.get()); | |
| 703 lock_.AssertAcquired(); | 760 lock_.AssertAcquired(); |
| 704 | 761 |
| 705 if (error >= 0) { | 762 if (error >= 0) { |
| 706 read_callback_->RunWithParams(Tuple1<size_t>(error)); | 763 read_callback_->RunWithParams(Tuple1<size_t>(error)); |
| 707 } else { | 764 } else { |
| 708 read_callback_->RunWithParams( | 765 read_callback_->RunWithParams( |
| 709 Tuple1<size_t>(static_cast<size_t>(media::DataSource::kReadError))); | 766 Tuple1<size_t>(static_cast<size_t>(media::DataSource::kReadError))); |
| 710 } | 767 } |
| 711 | 768 |
| 712 read_callback_.reset(); | 769 read_callback_.reset(); |
| 713 read_position_ = 0; | 770 read_position_ = 0; |
| 714 read_size_ = 0; | 771 read_size_ = 0; |
| 715 read_buffer_ = 0; | 772 read_buffer_ = 0; |
| 716 } | 773 } |
| 717 | 774 |
| 718 void BufferedDataSource::DoneInitialization() { | 775 void BufferedDataSource::DoneInitialization_Locked() { |
| 776 DCHECK(MessageLoop::current() == render_loop_); | |
| 719 DCHECK(initialize_callback_.get()); | 777 DCHECK(initialize_callback_.get()); |
| 720 lock_.AssertAcquired(); | 778 lock_.AssertAcquired(); |
| 721 | 779 |
| 722 initialize_callback_->Run(); | 780 initialize_callback_->Run(); |
| 723 initialize_callback_.reset(); | 781 initialize_callback_.reset(); |
| 724 } | 782 } |
| 725 | 783 |
| 726 ///////////////////////////////////////////////////////////////////////////// | 784 ///////////////////////////////////////////////////////////////////////////// |
| 727 // BufferedDataSource, callback methods. | 785 // BufferedDataSource, callback methods. |
| 728 // These methods are called on the render thread for the events reported by | 786 // These methods are called on the render thread for the events reported by |
| 729 // BufferedResourceLoader. | 787 // BufferedResourceLoader. |
| 730 void BufferedDataSource::HttpInitialStartCallback(int error) { | 788 void BufferedDataSource::HttpInitialStartCallback(int error) { |
| 731 DCHECK(MessageLoop::current() == render_loop_); | 789 DCHECK(MessageLoop::current() == render_loop_); |
| 790 DCHECK(loader_.get()); | |
| 791 | |
| 792 int64 instance_size = loader_->instance_size(); | |
| 793 bool partial_response = loader_->partial_response(); | |
| 794 bool success = error == net::OK; | |
| 795 | |
| 796 if (success) { | |
| 797 // TODO(hclam): Needs more thinking about supporting servers without range | |
| 798 // request or their partial response is not complete. | |
| 799 total_bytes_ = instance_size; | |
| 800 loaded_ = false; | |
| 801 streaming_ = (instance_size == kPositionNotSpecified) || !partial_response; | |
| 802 } else { | |
| 803 // TODO(hclam): In case of failure, we can retry several times. | |
| 804 loader_->Stop(); | |
| 805 } | |
| 732 | 806 |
| 733 // We need to prevent calling to filter host and running the callback if | 807 // We need to prevent calling to filter host and running the callback if |
| 734 // we have received the stop signal. We need to lock down the whole callback | 808 // we have received the stop signal. We need to lock down the whole callback |
| 735 // method to prevent bad things from happening. The reason behind this is | 809 // method to prevent bad things from happening. The reason behind this is |
| 736 // that we cannot guarantee tasks on render thread have completely stopped | 810 // that we cannot guarantee tasks on render thread have completely stopped |
| 737 // when we receive the Stop() method call. The only way to solve this is to | 811 // when we receive the Stop() method call. The only way to solve this is to |
| 738 // let tasks on render thread to run but make sure they don't call outside | 812 // let tasks on render thread to run but make sure they don't call outside |
| 739 // this object when Stop() method is ever called. Locking this method is safe | 813 // this object when Stop() method is ever called. Locking this method is safe |
| 740 // because |lock_| is only acquired in tasks on render thread. | 814 // because |lock_| is only acquired in tasks on render thread. |
| 741 AutoLock auto_lock(lock_); | 815 AutoLock auto_lock(lock_); |
| 742 if (stopped_) | 816 if (stop_signal_received_) |
| 743 return; | 817 return; |
| 744 | 818 |
| 745 if (error != net::OK) { | 819 if (!success) { |
| 746 // TODO(hclam): In case of failure, we can retry several times. | |
| 747 host()->SetError(media::PIPELINE_ERROR_NETWORK); | 820 host()->SetError(media::PIPELINE_ERROR_NETWORK); |
| 748 DCHECK(loader_.get()); | 821 DoneInitialization_Locked(); |
| 749 loader_->Stop(); | |
| 750 DoneInitialization(); | |
| 751 return; | 822 return; |
| 752 } | 823 } |
| 753 | 824 |
| 754 // TODO(hclam): Needs more thinking about supporting servers without range | 825 if (streaming_) { |
| 755 // request or their partial response is not complete. | 826 // If the server didn't reply with an instance size, it is likely this |
| 756 total_bytes_ = loader_->instance_size(); | 827 // is a streaming response. |
| 757 if (total_bytes_ >= 0 && loader_->partial_response()) { | 828 host()->SetStreaming(true); |
| 829 } else { | |
| 758 // This value governs the range that we can seek to. | 830 // This value governs the range that we can seek to. |
| 759 // TODO(hclam): Report the correct value of buffered bytes. | 831 // TODO(hclam): Report the correct value of buffered bytes. |
| 760 host()->SetTotalBytes(total_bytes_); | 832 host()->SetTotalBytes(total_bytes_); |
| 761 host()->SetBufferedBytes(total_bytes_); | 833 host()->SetBufferedBytes(0); |
| 762 } else { | |
| 763 // If the server didn't reply with an instance size, it is likely this | |
| 764 // is a streaming response. | |
| 765 streaming_ = true; | |
| 766 host()->SetStreaming(true); | |
| 767 } | 834 } |
| 768 | 835 |
| 769 // Currently, only files can be used reliably w/o a network. | 836 // Currently, only files can be used reliably w/o a network. |
| 770 host()->SetLoaded(false); | 837 host()->SetLoaded(false); |
| 771 DoneInitialization(); | 838 DoneInitialization_Locked(); |
| 772 } | 839 } |
| 773 | 840 |
| 774 void BufferedDataSource::NonHttpInitialStartCallback(int error) { | 841 void BufferedDataSource::NonHttpInitialStartCallback(int error) { |
| 775 DCHECK(MessageLoop::current() == render_loop_); | 842 DCHECK(MessageLoop::current() == render_loop_); |
| 843 DCHECK(loader_.get()); | |
| 844 | |
| 845 int64 instance_size = loader_->instance_size(); | |
| 846 bool success = error == net::OK && instance_size != kPositionNotSpecified; | |
| 847 | |
| 848 if (success) { | |
| 849 total_bytes_ = instance_size; | |
| 850 loaded_ = true; | |
| 851 } else { | |
| 852 loader_->Stop(); | |
| 853 } | |
| 776 | 854 |
| 777 // We need to prevent calling to filter host and running the callback if | 855 // We need to prevent calling to filter host and running the callback if |
| 778 // we have received the stop signal. We need to lock down the whole callback | 856 // we have received the stop signal. We need to lock down the whole callback |
| 779 // method to prevent bad things from happening. The reason behind this is | 857 // method to prevent bad things from happening. The reason behind this is |
| 780 // that we cannot guarantee tasks on render thread have completely stopped | 858 // that we cannot guarantee tasks on render thread have completely stopped |
| 781 // when we receive the Stop() method call. The only way to solve this is to | 859 // when we receive the Stop() method call. The only way to solve this is to |
| 782 // let tasks on render thread to run but make sure they don't call outside | 860 // let tasks on render thread to run but make sure they don't call outside |
| 783 // this object when Stop() method is ever called. Locking this method is safe | 861 // this object when Stop() method is ever called. Locking this method is safe |
| 784 // because |lock_| is only acquired in tasks on render thread. | 862 // because |lock_| is only acquired in tasks on render thread. |
| 785 AutoLock auto_lock(lock_); | 863 AutoLock auto_lock(lock_); |
| 786 if (stopped_) | 864 if (stop_signal_received_) |
| 787 return; | 865 return; |
| 788 | 866 |
| 789 DCHECK(loader_.get()); | 867 if (success) { |
| 790 | 868 host()->SetTotalBytes(total_bytes_); |
| 791 if (error != net::OK || loader_->instance_size() == kPositionNotSpecified) { | 869 host()->SetBufferedBytes(total_bytes_); |
| 870 host()->SetLoaded(loaded_); | |
| 871 } else { | |
| 792 host()->SetError(media::PIPELINE_ERROR_NETWORK); | 872 host()->SetError(media::PIPELINE_ERROR_NETWORK); |
| 793 loader_->Stop(); | |
| 794 DoneInitialization(); | |
| 795 return; | |
| 796 } | 873 } |
| 797 | 874 DoneInitialization_Locked(); |
| 798 total_bytes_ = loader_->instance_size(); | |
| 799 host()->SetTotalBytes(total_bytes_); | |
| 800 host()->SetBufferedBytes(total_bytes_); | |
| 801 host()->SetLoaded(true); | |
| 802 DoneInitialization(); | |
| 803 } | 875 } |
| 804 | 876 |
| 805 void BufferedDataSource::PartialReadStartCallback(int error) { | 877 void BufferedDataSource::PartialReadStartCallback(int error) { |
| 806 DCHECK(MessageLoop::current() == render_loop_); | 878 DCHECK(MessageLoop::current() == render_loop_); |
| 807 DCHECK(loader_.get()); | 879 DCHECK(loader_.get()); |
| 808 | 880 |
| 809 // This callback method is invoked after we have verified the server has | 881 // This callback method is invoked after we have verified the server has |
| 810 // range request capability, so as a safety guard verify again the response | 882 // range request capability, so as a safety guard verify again the response |
| 811 // is partial. | 883 // is partial. |
| 812 if (error == net::OK && loader_->partial_response()) { | 884 if (error == net::OK && loader_->partial_response()) { |
| 813 // Once the range request has started successfully, we can proceed with | 885 // Once the range request has started successfully, we can proceed with |
| 814 // reading from it. | 886 // reading from it. |
| 815 ReadInternal(); | 887 ReadInternal(); |
| 816 } else { | 888 return; |
| 817 loader_->Stop(); | 889 } |
| 818 | 890 |
| 819 // We need to prevent calling to filter host and running the callback if | 891 // Stop the resource loader since we have received an error. |
| 820 // we have received the stop signal. We need to lock down the whole callback | 892 loader_->Stop(); |
| 821 // method to prevent bad things from happening. The reason behind this is | 893 |
| 822 // that we cannot guarantee tasks on render thread have completely stopped | 894 // We need to prevent calling to filter host and running the callback if |
| 823 // when we receive the Stop() method call. So only way to solve this is to | 895 // we have received the stop signal. We need to lock down the whole callback |
| 824 // let tasks on render thread to run but make sure they don't call outside | 896 // method to prevent bad things from happening. The reason behind this is |
| 825 // this object when Stop() method is ever called. Locking this method is | 897 // that we cannot guarantee tasks on render thread have completely stopped |
| 826 // safe because |lock_| is only acquired in tasks on render thread. | 898 // when we receive the Stop() method call. So only way to solve this is to |
| 827 AutoLock auto_lock(lock_); | 899 // let tasks on render thread to run but make sure they don't call outside |
| 828 if (stopped_) | 900 // this object when Stop() method is ever called. Locking this method is |
| 829 return; | 901 // safe because |lock_| is only acquired in tasks on render thread. |
| 830 DoneRead(net::ERR_INVALID_RESPONSE); | 902 AutoLock auto_lock(lock_); |
| 831 } | 903 if (stop_signal_received_) |
| 904 return; | |
| 905 DoneRead_Locked(net::ERR_INVALID_RESPONSE); | |
| 832 } | 906 } |
| 833 | 907 |
| 834 void BufferedDataSource::ReadCallback(int error) { | 908 void BufferedDataSource::ReadCallback(int error) { |
| 835 DCHECK(MessageLoop::current() == render_loop_); | 909 DCHECK(MessageLoop::current() == render_loop_); |
| 836 | 910 |
| 911 if (error < 0) { | |
| 912 DCHECK(loader_.get()); | |
| 913 | |
| 914 // Stop the resource load if it failed. | |
| 915 loader_->Stop(); | |
| 916 | |
| 917 if (error == net::ERR_CACHE_MISS) { | |
| 918 render_loop_->PostTask(FROM_HERE, | |
| 919 NewRunnableMethod(this, &BufferedDataSource::RestartLoadingTask)); | |
| 920 return; | |
| 921 } | |
| 922 } | |
| 923 | |
| 837 // We need to prevent calling to filter host and running the callback if | 924 // We need to prevent calling to filter host and running the callback if |
| 838 // we have received the stop signal. We need to lock down the whole callback | 925 // we have received the stop signal. We need to lock down the whole callback |
| 839 // method to prevent bad things from happening. The reason behind this is | 926 // method to prevent bad things from happening. The reason behind this is |
| 840 // that we cannot guarantee tasks on render thread have completely stopped | 927 // that we cannot guarantee tasks on render thread have completely stopped |
| 841 // when we receive the Stop() method call. So only way to solve this is to | 928 // when we receive the Stop() method call. So only way to solve this is to |
| 842 // let tasks on render thread to run but make sure they don't call outside | 929 // let tasks on render thread to run but make sure they don't call outside |
| 843 // this object when Stop() method is ever called. Locking this method is safe | 930 // this object when Stop() method is ever called. Locking this method is safe |
| 844 // because |lock_| is only acquired in tasks on render thread. | 931 // because |lock_| is only acquired in tasks on render thread. |
| 845 AutoLock auto_lock(lock_); | 932 AutoLock auto_lock(lock_); |
| 846 if (stopped_) | 933 if (stop_signal_received_) |
| 847 return; | 934 return; |
| 848 | 935 |
| 849 DCHECK(loader_.get()); | 936 if (error > 0) { |
| 850 DCHECK(read_callback_.get()); | |
| 851 | |
| 852 if (error >= 0) { | |
| 853 // If a position error code is received, read was successful. So copy | 937 // If a position error code is received, read was successful. So copy |
| 854 // from intermediate read buffer to the target read buffer. | 938 // from intermediate read buffer to the target read buffer. |
| 855 memcpy(read_buffer_, intermediate_read_buffer_.get(), error); | 939 memcpy(read_buffer_, intermediate_read_buffer_.get(), error); |
| 856 DoneRead(error); | 940 } |
| 857 } else if (error == net::ERR_CACHE_MISS) { | 941 DoneRead_Locked(error); |
| 858 // If the current loader cannot serve this read request, we need to create | 942 } |
| 859 // a new one. | |
| 860 // TODO(hclam): we need to count how many times it failed to prevent | |
| 861 // excessive trials. | |
| 862 | 943 |
| 863 // Stops the current resource loader. | 944 void BufferedDataSource::NetworkEventCallback() { |
| 864 loader_->Stop(); | 945 DCHECK(MessageLoop::current() == render_loop_); |
| 946 DCHECK(loader_.get()); | |
| 865 | 947 |
| 866 // Since this method is called from the current buffered resource loader, | 948 // In case of non-HTTP request we don't need to report network events, |
| 867 // we cannot delete it. So we need to post a task to swap in a new | 949 // so return immediately. |
| 868 // resource loader and starts it. | 950 if (loaded_) |
| 869 render_loop_->PostTask(FROM_HERE, | 951 return; |
| 870 NewRunnableMethod(this, &BufferedDataSource::SwapLoaderTask, | 952 |
| 871 CreateLoader(read_position_, -1))); | 953 bool network_activity = loader_->network_activity(); |
| 872 } else { | 954 int64 buffered_last_byte_position = loader_->GetBufferedLastBytePosition(); |
| 873 loader_->Stop(); | 955 |
| 874 DoneRead(error); | 956 // If we get an unspecified value, return immediately. |
| 957 if (buffered_last_byte_position == kPositionNotSpecified) | |
| 958 return; | |
| 959 | |
| 960 // We need to prevent calling to filter host and running the callback if | |
| 961 // we have received the stop signal. We need to lock down the whole callback | |
| 962 // method to prevent bad things from happening. The reason behind this is | |
| 963 // that we cannot guarantee tasks on render thread have completely stopped | |
| 964 // when we receive the Stop() method call. So only way to solve this is to | |
| 965 // let tasks on render thread to run but make sure they don't call outside | |
| 966 // this object when Stop() method is ever called. Locking this method is safe | |
| 967 // because |lock_| is only acquired in tasks on render thread. | |
| 968 AutoLock auto_lock(lock_); | |
| 969 if (stop_signal_received_) | |
| 970 return; | |
| 971 | |
| 972 if (network_activity != network_activity_) { | |
| 973 network_activity_ = network_activity; | |
| 974 host()->SetNetworkActivity(network_activity); | |
| 875 } | 975 } |
| 976 host()->SetBufferedBytes(buffered_last_byte_position + 1); | |
| 876 } | 977 } |
| 877 | 978 |
| 878 } // namespace webkit_glue | 979 } // namespace webkit_glue |
| OLD | NEW |