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 |