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