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 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 // won't result in synchronously calling into a ResourceHandler, if this | 506 // won't result in synchronously calling into a ResourceHandler, if this |
507 // was called from Resume(). | 507 // was called from Resume(). |
508 StartRequestInternal(); | 508 StartRequestInternal(); |
509 break; | 509 break; |
510 case DEFERRED_REDIRECT: | 510 case DEFERRED_REDIRECT: |
511 // URLRequest::Start completes asynchronously, so starting the request now | 511 // URLRequest::Start completes asynchronously, so starting the request now |
512 // won't result in synchronously calling into a ResourceHandler, if this | 512 // won't result in synchronously calling into a ResourceHandler, if this |
513 // was called from Resume(). | 513 // was called from Resume(). |
514 FollowDeferredRedirectInternal(); | 514 FollowDeferredRedirectInternal(); |
515 break; | 515 break; |
| 516 case DEFERRED_ON_WILL_READ: |
| 517 // Always post a task, as synchronous resumes don't go through this |
| 518 // method. |
| 519 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 520 FROM_HERE, base::Bind(&ResourceLoader::ReadMore, |
| 521 weak_ptr_factory_.GetWeakPtr(), false)); |
| 522 break; |
516 case DEFERRED_READ: | 523 case DEFERRED_READ: |
517 if (called_from_resource_controller) { | 524 if (called_from_resource_controller) { |
518 // TODO(mmenke): Call ReadMore instead? Strange that this is the only | 525 // TODO(mmenke): Call PrepareToReadMore instead? Strange that this is |
519 // 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? |
520 base::ThreadTaskRunnerHandle::Get()->PostTask( | 529 base::ThreadTaskRunnerHandle::Get()->PostTask( |
521 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, | 530 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, |
522 weak_ptr_factory_.GetWeakPtr())); | 531 weak_ptr_factory_.GetWeakPtr())); |
523 } else { | 532 } else { |
524 // 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, |
525 // 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 |
526 // avoid blocking the IO thread. | 535 // avoid blocking the IO thread. |
527 ReadMore(true /* handle_result_asynchronously */); | 536 PrepareToReadMore(true /* handle_result_asynchronously */); |
528 } | 537 } |
529 break; | 538 break; |
530 case DEFERRED_RESPONSE_COMPLETE: | 539 case DEFERRED_RESPONSE_COMPLETE: |
531 if (called_from_resource_controller) { | 540 if (called_from_resource_controller) { |
532 base::ThreadTaskRunnerHandle::Get()->PostTask( | 541 base::ThreadTaskRunnerHandle::Get()->PostTask( |
533 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, | 542 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, |
534 weak_ptr_factory_.GetWeakPtr())); | 543 weak_ptr_factory_.GetWeakPtr())); |
535 } else { | 544 } else { |
536 ResponseCompleted(); | 545 ResponseCompleted(); |
537 } | 546 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | 649 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
641 tracked_objects::ScopedTracker tracking_profile( | 650 tracked_objects::ScopedTracker tracking_profile( |
642 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); | 651 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); |
643 | 652 |
644 read_deferral_start_time_ = base::TimeTicks::Now(); | 653 read_deferral_start_time_ = base::TimeTicks::Now(); |
645 ScopedDeferral scoped_deferral(this, DEFERRED_READ); | 654 ScopedDeferral scoped_deferral(this, DEFERRED_READ); |
646 handler_->OnResponseStarted(response.get(), | 655 handler_->OnResponseStarted(response.get(), |
647 base::MakeUnique<Controller>(this)); | 656 base::MakeUnique<Controller>(this)); |
648 } | 657 } |
649 | 658 |
650 void ResourceLoader::ReadMore(bool handle_result_async) { | 659 void ResourceLoader::PrepareToReadMore(bool handle_result_async) { |
651 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this, | 660 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::PrepareToReadMore", this, |
652 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 661 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
653 DCHECK(!is_deferred()); | 662 DCHECK(!is_deferred()); |
654 | 663 |
655 // Make sure we track the buffer in at least one place. This ensures it gets | 664 deferred_stage_ = DEFERRED_SYNC; |
656 // deleted even in the case the request has already finished its job and | 665 |
657 // doesn't use the buffer. | |
658 scoped_refptr<net::IOBuffer> buf; | |
659 int buf_size; | |
660 { | 666 { |
661 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | 667 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
662 tracked_objects::ScopedTracker tracking_profile2( | 668 tracked_objects::ScopedTracker tracking_profile2( |
663 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnWillRead()")); | 669 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnWillRead()")); |
664 | 670 |
665 if (!handler_->OnWillRead(&buf, &buf_size)) { | 671 handler_->OnWillRead(&read_buffer_, &read_buffer_size_, |
666 // Cancel the request, which will then call back into |this| to inform it | 672 base::MakeUnique<Controller>(this)); |
667 // of a "read error". | |
668 Cancel(); | |
669 return; | |
670 } | |
671 } | 673 } |
672 | 674 |
673 DCHECK(buf.get()); | 675 if (is_deferred()) { |
674 DCHECK(buf_size > 0); | 676 deferred_stage_ = DEFERRED_ON_WILL_READ; |
| 677 } else { |
| 678 ReadMore(handle_result_async); |
| 679 } |
| 680 } |
675 | 681 |
676 int result = request_->Read(buf.get(), buf_size); | 682 void ResourceLoader::ReadMore(bool handle_result_async) { |
| 683 DCHECK(read_buffer_.get()); |
| 684 DCHECK_GT(read_buffer_size_, 0); |
| 685 |
| 686 int result = request_->Read(read_buffer_.get(), read_buffer_size_); |
| 687 // Have to do this after the Read call, to ensure it still has an outstanding |
| 688 // reference. |
| 689 read_buffer_ = nullptr; |
| 690 read_buffer_size_ = 0; |
677 | 691 |
678 if (result == net::ERR_IO_PENDING) | 692 if (result == net::ERR_IO_PENDING) |
679 return; | 693 return; |
680 | 694 |
681 if (!handle_result_async || result <= 0) { | 695 if (!handle_result_async || result <= 0) { |
682 OnReadCompleted(request_.get(), result); | 696 OnReadCompleted(request_.get(), result); |
683 } else { | 697 } else { |
684 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO | 698 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
685 // thread in case the URLRequest can provide data synchronously. | 699 // thread in case the URLRequest can provide data synchronously. |
686 base::ThreadTaskRunnerHandle::Get()->PostTask( | 700 base::ThreadTaskRunnerHandle::Get()->PostTask( |
687 FROM_HERE, | 701 FROM_HERE, |
688 base::Bind(&ResourceLoader::OnReadCompleted, | 702 base::Bind(&ResourceLoader::OnReadCompleted, |
689 weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); | 703 weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); |
690 } | 704 } |
691 } | 705 } |
692 | 706 |
693 void ResourceLoader::ResumeReading() { | 707 void ResourceLoader::ResumeReading() { |
694 DCHECK(!is_deferred()); | 708 DCHECK(!is_deferred()); |
695 | 709 |
696 if (!read_deferral_start_time_.is_null()) { | 710 if (!read_deferral_start_time_.is_null()) { |
697 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", | 711 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", |
698 base::TimeTicks::Now() - read_deferral_start_time_); | 712 base::TimeTicks::Now() - read_deferral_start_time_); |
699 read_deferral_start_time_ = base::TimeTicks(); | 713 read_deferral_start_time_ = base::TimeTicks(); |
700 } | 714 } |
701 if (request_->status().is_success()) { | 715 if (request_->status().is_success()) { |
702 ReadMore(false /* handle_result_asynchronously */); | 716 PrepareToReadMore(false /* handle_result_asynchronously */); |
703 } else { | 717 } else { |
704 ResponseCompleted(); | 718 ResponseCompleted(); |
705 } | 719 } |
706 } | 720 } |
707 | 721 |
708 void ResourceLoader::CompleteRead(int bytes_read) { | 722 void ResourceLoader::CompleteRead(int bytes_read) { |
709 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, | 723 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, |
710 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 724 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
711 | 725 |
712 DCHECK(bytes_read >= 0); | 726 DCHECK(bytes_read >= 0); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status, | 816 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status, |
803 STATUS_MAX); | 817 STATUS_MAX); |
804 } | 818 } |
805 } else if (request_->response_info().unused_since_prefetch) { | 819 } else if (request_->response_info().unused_since_prefetch) { |
806 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); | 820 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); |
807 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); | 821 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); |
808 } | 822 } |
809 } | 823 } |
810 | 824 |
811 } // namespace content | 825 } // namespace content |
OLD | NEW |