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/loader/resource_loader.h" | 5 #include "content/browser/loader/resource_loader.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 // won't result in synchronously calling into a ResourceHandler, if this | 505 // won't result in synchronously calling into a ResourceHandler, if this |
| 506 // was called from Resume(). | 506 // was called from Resume(). |
| 507 StartRequestInternal(); | 507 StartRequestInternal(); |
| 508 break; | 508 break; |
| 509 case DEFERRED_REDIRECT: | 509 case DEFERRED_REDIRECT: |
| 510 // URLRequest::Start completes asynchronously, so starting the request now | 510 // URLRequest::Start completes asynchronously, so starting the request now |
| 511 // won't result in synchronously calling into a ResourceHandler, if this | 511 // won't result in synchronously calling into a ResourceHandler, if this |
| 512 // was called from Resume(). | 512 // was called from Resume(). |
| 513 FollowDeferredRedirectInternal(); | 513 FollowDeferredRedirectInternal(); |
| 514 break; | 514 break; |
| 515 case DEFERRED_ON_WILL_READ: | |
| 516 // Always post a task, as synchronous resumes don't go through this | |
| 517 // method. | |
| 518 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 519 FROM_HERE, base::Bind(&ResourceLoader::ReadMore, | |
| 520 weak_ptr_factory_.GetWeakPtr(), false)); | |
|
Charlie Harrison
2017/03/08 21:12:46
nit: false /* handle_result_asynchronously */
mmenke
2017/03/08 22:51:30
Done.
| |
| 521 break; | |
| 515 case DEFERRED_READ: | 522 case DEFERRED_READ: |
| 516 if (called_from_resource_controller) { | 523 if (called_from_resource_controller) { |
| 517 // TODO(mmenke): Call ReadMore instead? Strange that this is the only | 524 // TODO(mmenke): Call PrepareToReadMore instead? Strange that this is |
| 518 // path which calls different methods, depending on the path. | 525 // the only case which calls different methods, depending on the path. |
| 526 // ResumeReading does check for cancellation. Should other paths do that | |
| 527 // as well? | |
| 519 base::ThreadTaskRunnerHandle::Get()->PostTask( | 528 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 520 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, | 529 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, |
| 521 weak_ptr_factory_.GetWeakPtr())); | 530 weak_ptr_factory_.GetWeakPtr())); |
| 522 } else { | 531 } else { |
| 523 // If this was called as a result of a handler succeeding synchronously, | 532 // If this was called as a result of a handler succeeding synchronously, |
| 524 // force the result of the next read to be handled asynchronously, to | 533 // force the result of the next read to be handled asynchronously, to |
| 525 // avoid blocking the IO thread. | 534 // avoid blocking the IO thread. |
| 526 ReadMore(true /* handle_result_asynchronously */); | 535 PrepareToReadMore(true /* handle_result_asynchronously */); |
| 527 } | 536 } |
| 528 break; | 537 break; |
| 529 case DEFERRED_RESPONSE_COMPLETE: | 538 case DEFERRED_RESPONSE_COMPLETE: |
| 530 if (called_from_resource_controller) { | 539 if (called_from_resource_controller) { |
| 531 base::ThreadTaskRunnerHandle::Get()->PostTask( | 540 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 532 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, | 541 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, |
| 533 weak_ptr_factory_.GetWeakPtr())); | 542 weak_ptr_factory_.GetWeakPtr())); |
| 534 } else { | 543 } else { |
| 535 ResponseCompleted(); | 544 ResponseCompleted(); |
| 536 } | 545 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 | 640 |
| 632 void ResourceLoader::CompleteResponseStarted() { | 641 void ResourceLoader::CompleteResponseStarted() { |
| 633 ResourceRequestInfoImpl* info = GetRequestInfo(); | 642 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 634 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | 643 scoped_refptr<ResourceResponse> response = new ResourceResponse(); |
| 635 PopulateResourceResponse(info, request_.get(), response.get()); | 644 PopulateResourceResponse(info, request_.get(), response.get()); |
| 636 | 645 |
| 637 delegate_->DidReceiveResponse(this); | 646 delegate_->DidReceiveResponse(this); |
| 638 | 647 |
| 639 read_deferral_start_time_ = base::TimeTicks::Now(); | 648 read_deferral_start_time_ = base::TimeTicks::Now(); |
| 640 // Using a ScopedDeferral here would result in calling ReadMore(true) on sync | 649 // Using a ScopedDeferral here would result in calling ReadMore(true) on sync |
| 641 // success. Calling ReadMore(false) here instead allows small responses to be | 650 // success. Calling PrepareToReadMore(false) here instead allows small |
| 642 // handled completely synchronously, if no ResourceHandler defers handling of | 651 // responses to be handled completely synchronously, if no ResourceHandler |
| 643 // the response. | 652 // defers handling of the response. |
| 644 deferred_stage_ = DEFERRED_SYNC; | 653 deferred_stage_ = DEFERRED_SYNC; |
| 645 handler_->OnResponseStarted(response.get(), | 654 handler_->OnResponseStarted(response.get(), |
| 646 base::MakeUnique<Controller>(this)); | 655 base::MakeUnique<Controller>(this)); |
| 647 if (is_deferred()) { | 656 if (is_deferred()) { |
| 648 deferred_stage_ = DEFERRED_READ; | 657 deferred_stage_ = DEFERRED_READ; |
| 649 } else { | 658 } else { |
| 650 ReadMore(false); | 659 PrepareToReadMore(false); |
| 660 } | |
| 661 } | |
| 662 | |
| 663 void ResourceLoader::PrepareToReadMore(bool handle_result_async) { | |
| 664 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::PrepareToReadMore", this, | |
| 665 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | |
| 666 DCHECK(!is_deferred()); | |
| 667 | |
| 668 deferred_stage_ = DEFERRED_SYNC; | |
| 669 | |
| 670 handler_->OnWillRead(&read_buffer_, &read_buffer_size_, | |
| 671 base::MakeUnique<Controller>(this)); | |
| 672 | |
| 673 if (is_deferred()) { | |
| 674 deferred_stage_ = DEFERRED_ON_WILL_READ; | |
| 675 } else { | |
| 676 ReadMore(handle_result_async); | |
| 651 } | 677 } |
| 652 } | 678 } |
| 653 | 679 |
| 654 void ResourceLoader::ReadMore(bool handle_result_async) { | 680 void ResourceLoader::ReadMore(bool handle_result_async) { |
| 655 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this, | 681 DCHECK(read_buffer_.get()); |
| 656 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 682 DCHECK_GT(read_buffer_size_, 0); |
| 657 DCHECK(!is_deferred()); | |
| 658 | 683 |
| 659 // Make sure we track the buffer in at least one place. This ensures it gets | 684 int result = request_->Read(read_buffer_.get(), read_buffer_size_); |
| 660 // deleted even in the case the request has already finished its job and | 685 // Have to do this after the Read call, to ensure it still has an outstanding |
| 661 // doesn't use the buffer. | 686 // reference. |
| 662 scoped_refptr<net::IOBuffer> buf; | 687 read_buffer_ = nullptr; |
| 663 int buf_size; | 688 read_buffer_size_ = 0; |
| 664 if (!handler_->OnWillRead(&buf, &buf_size)) { | |
| 665 // Cancel the request, which will then call back into |this| to inform it of | |
| 666 // a "read error". | |
| 667 Cancel(); | |
| 668 return; | |
| 669 } | |
| 670 | |
| 671 DCHECK(buf.get()); | |
| 672 DCHECK(buf_size > 0); | |
| 673 | |
| 674 int result = request_->Read(buf.get(), buf_size); | |
| 675 | 689 |
| 676 if (result == net::ERR_IO_PENDING) | 690 if (result == net::ERR_IO_PENDING) |
| 677 return; | 691 return; |
| 678 | 692 |
| 679 if (!handle_result_async || result <= 0) { | 693 if (!handle_result_async || result <= 0) { |
| 680 OnReadCompleted(request_.get(), result); | 694 OnReadCompleted(request_.get(), result); |
| 681 } else { | 695 } else { |
| 682 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO | 696 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
| 683 // thread in case the URLRequest can provide data synchronously. | 697 // thread in case the URLRequest can provide data synchronously. |
| 684 base::ThreadTaskRunnerHandle::Get()->PostTask( | 698 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 685 FROM_HERE, | 699 FROM_HERE, |
| 686 base::Bind(&ResourceLoader::OnReadCompleted, | 700 base::Bind(&ResourceLoader::OnReadCompleted, |
| 687 weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); | 701 weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); |
| 688 } | 702 } |
| 689 } | 703 } |
| 690 | 704 |
| 691 void ResourceLoader::ResumeReading() { | 705 void ResourceLoader::ResumeReading() { |
| 692 DCHECK(!is_deferred()); | 706 DCHECK(!is_deferred()); |
| 693 | 707 |
| 694 if (!read_deferral_start_time_.is_null()) { | 708 if (!read_deferral_start_time_.is_null()) { |
| 695 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", | 709 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", |
| 696 base::TimeTicks::Now() - read_deferral_start_time_); | 710 base::TimeTicks::Now() - read_deferral_start_time_); |
| 697 read_deferral_start_time_ = base::TimeTicks(); | 711 read_deferral_start_time_ = base::TimeTicks(); |
| 698 } | 712 } |
| 699 if (request_->status().is_success()) { | 713 if (request_->status().is_success()) { |
| 700 ReadMore(false /* handle_result_asynchronously */); | 714 PrepareToReadMore(false /* handle_result_asynchronously */); |
| 701 } else { | 715 } else { |
| 702 ResponseCompleted(); | 716 ResponseCompleted(); |
| 703 } | 717 } |
| 704 } | 718 } |
| 705 | 719 |
| 706 void ResourceLoader::CompleteRead(int bytes_read) { | 720 void ResourceLoader::CompleteRead(int bytes_read) { |
| 707 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, | 721 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, |
| 708 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 722 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
| 709 | 723 |
| 710 DCHECK(bytes_read >= 0); | 724 DCHECK(bytes_read >= 0); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status, | 806 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status, |
| 793 STATUS_MAX); | 807 STATUS_MAX); |
| 794 } | 808 } |
| 795 } else if (request_->response_info().unused_since_prefetch) { | 809 } else if (request_->response_info().unused_since_prefetch) { |
| 796 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); | 810 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); |
| 797 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); | 811 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); |
| 798 } | 812 } |
| 799 } | 813 } |
| 800 | 814 |
| 801 } // namespace content | 815 } // namespace content |
| OLD | NEW |