Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: net/dns/host_resolver_impl.cc

Issue 1137433003: Encouraging ThreadTaskRunnerHandle usage in net/dns module (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed build failure Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/dns/serial_worker.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "net/dns/host_resolver_impl.h" 5 #include "net/dns/host_resolver_impl.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <Winsock2.h> 8 #include <Winsock2.h>
9 #elif defined(OS_POSIX) 9 #elif defined(OS_POSIX)
10 #include <netdb.h> 10 #include <netdb.h>
11 #endif 11 #endif
12 12
13 #include <cmath> 13 #include <cmath>
14 #include <utility> 14 #include <utility>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/basictypes.h" 17 #include "base/basictypes.h"
18 #include "base/bind.h" 18 #include "base/bind.h"
19 #include "base/bind_helpers.h" 19 #include "base/bind_helpers.h"
20 #include "base/callback.h" 20 #include "base/callback.h"
21 #include "base/compiler_specific.h" 21 #include "base/compiler_specific.h"
22 #include "base/debug/debugger.h" 22 #include "base/debug/debugger.h"
23 #include "base/debug/stack_trace.h" 23 #include "base/debug/stack_trace.h"
24 #include "base/message_loop/message_loop_proxy.h"
25 #include "base/metrics/field_trial.h" 24 #include "base/metrics/field_trial.h"
26 #include "base/metrics/histogram_macros.h" 25 #include "base/metrics/histogram_macros.h"
27 #include "base/metrics/sparse_histogram.h" 26 #include "base/metrics/sparse_histogram.h"
28 #include "base/profiler/scoped_tracker.h" 27 #include "base/profiler/scoped_tracker.h"
28 #include "base/single_thread_task_runner.h"
29 #include "base/stl_util.h" 29 #include "base/stl_util.h"
30 #include "base/strings/string_util.h" 30 #include "base/strings/string_util.h"
31 #include "base/strings/utf_string_conversions.h" 31 #include "base/strings/utf_string_conversions.h"
32 #include "base/thread_task_runner_handle.h"
32 #include "base/threading/worker_pool.h" 33 #include "base/threading/worker_pool.h"
33 #include "base/time/time.h" 34 #include "base/time/time.h"
34 #include "base/values.h" 35 #include "base/values.h"
35 #include "net/base/address_family.h" 36 #include "net/base/address_family.h"
36 #include "net/base/address_list.h" 37 #include "net/base/address_list.h"
37 #include "net/base/dns_reloader.h" 38 #include "net/base/dns_reloader.h"
38 #include "net/base/dns_util.h" 39 #include "net/base/dns_util.h"
39 #include "net/base/host_port_pair.h" 40 #include "net/base/host_port_pair.h"
40 #include "net/base/ip_endpoint.h" 41 #include "net/base/ip_endpoint.h"
41 #include "net/base/net_errors.h" 42 #include "net/base/net_errors.h"
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 typedef base::Callback<void(int net_error, 592 typedef base::Callback<void(int net_error,
592 const AddressList& addr_list)> Callback; 593 const AddressList& addr_list)> Callback;
593 594
594 ProcTask(const Key& key, 595 ProcTask(const Key& key,
595 const ProcTaskParams& params, 596 const ProcTaskParams& params,
596 const Callback& callback, 597 const Callback& callback,
597 const BoundNetLog& job_net_log) 598 const BoundNetLog& job_net_log)
598 : key_(key), 599 : key_(key),
599 params_(params), 600 params_(params),
600 callback_(callback), 601 callback_(callback),
601 origin_loop_(base::MessageLoopProxy::current()), 602 task_runner_(base::ThreadTaskRunnerHandle::Get()),
602 attempt_number_(0), 603 attempt_number_(0),
603 completed_attempt_number_(0), 604 completed_attempt_number_(0),
604 completed_attempt_error_(ERR_UNEXPECTED), 605 completed_attempt_error_(ERR_UNEXPECTED),
605 had_non_speculative_request_(false), 606 had_non_speculative_request_(false),
606 net_log_(job_net_log) { 607 net_log_(job_net_log) {
607 if (!params_.resolver_proc.get()) 608 if (!params_.resolver_proc.get())
608 params_.resolver_proc = HostResolverProc::GetDefault(); 609 params_.resolver_proc = HostResolverProc::GetDefault();
609 // If default is unset, use the system proc. 610 // If default is unset, use the system proc.
610 if (!params_.resolver_proc.get()) 611 if (!params_.resolver_proc.get())
611 params_.resolver_proc = new SystemHostResolverProc(); 612 params_.resolver_proc = new SystemHostResolverProc();
612 } 613 }
613 614
614 void Start() { 615 void Start() {
615 DCHECK(origin_loop_->BelongsToCurrentThread()); 616 DCHECK(task_runner_->BelongsToCurrentThread());
616 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 617 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
617 StartLookupAttempt(); 618 StartLookupAttempt();
618 } 619 }
619 620
620 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve 621 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve
621 // attempts running on worker threads will continue running. Only once all the 622 // attempts running on worker threads will continue running. Only once all the
622 // attempts complete will the final reference to this ProcTask be released. 623 // attempts complete will the final reference to this ProcTask be released.
623 void Cancel() { 624 void Cancel() {
624 DCHECK(origin_loop_->BelongsToCurrentThread()); 625 DCHECK(task_runner_->BelongsToCurrentThread());
625 626
626 if (was_canceled() || was_completed()) 627 if (was_canceled() || was_completed())
627 return; 628 return;
628 629
629 callback_.Reset(); 630 callback_.Reset();
630 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 631 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
631 } 632 }
632 633
633 void set_had_non_speculative_request() { 634 void set_had_non_speculative_request() {
634 DCHECK(origin_loop_->BelongsToCurrentThread()); 635 DCHECK(task_runner_->BelongsToCurrentThread());
635 had_non_speculative_request_ = true; 636 had_non_speculative_request_ = true;
636 } 637 }
637 638
638 bool was_canceled() const { 639 bool was_canceled() const {
639 DCHECK(origin_loop_->BelongsToCurrentThread()); 640 DCHECK(task_runner_->BelongsToCurrentThread());
640 return callback_.is_null(); 641 return callback_.is_null();
641 } 642 }
642 643
643 bool was_completed() const { 644 bool was_completed() const {
644 DCHECK(origin_loop_->BelongsToCurrentThread()); 645 DCHECK(task_runner_->BelongsToCurrentThread());
645 return completed_attempt_number_ > 0; 646 return completed_attempt_number_ > 0;
646 } 647 }
647 648
648 private: 649 private:
649 friend class base::RefCountedThreadSafe<ProcTask>; 650 friend class base::RefCountedThreadSafe<ProcTask>;
650 ~ProcTask() {} 651 ~ProcTask() {}
651 652
652 void StartLookupAttempt() { 653 void StartLookupAttempt() {
653 DCHECK(origin_loop_->BelongsToCurrentThread()); 654 DCHECK(task_runner_->BelongsToCurrentThread());
654 base::TimeTicks start_time = base::TimeTicks::Now(); 655 base::TimeTicks start_time = base::TimeTicks::Now();
655 ++attempt_number_; 656 ++attempt_number_;
656 // Dispatch the lookup attempt to a worker thread. 657 // Dispatch the lookup attempt to a worker thread.
657 if (!base::WorkerPool::PostTask( 658 if (!base::WorkerPool::PostTask(
658 FROM_HERE, 659 FROM_HERE,
659 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), 660 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_),
660 true)) { 661 true)) {
661 NOTREACHED(); 662 NOTREACHED();
662 663
663 // Since we could be running within Resolve() right now, we can't just 664 // Since we could be running within Resolve() right now, we can't just
664 // call OnLookupComplete(). Instead we must wait until Resolve() has 665 // call OnLookupComplete(). Instead we must wait until Resolve() has
665 // returned (IO_PENDING). 666 // returned (IO_PENDING).
666 origin_loop_->PostTask( 667 task_runner_->PostTask(FROM_HERE,
667 FROM_HERE, 668 base::Bind(&ProcTask::OnLookupComplete,
668 base::Bind(&ProcTask::OnLookupComplete, this, AddressList(), 669 this,
669 start_time, attempt_number_, ERR_UNEXPECTED, 0)); 670 AddressList(),
671 start_time,
672 attempt_number_,
673 ERR_UNEXPECTED,
674 0));
670 return; 675 return;
671 } 676 }
672 677
673 net_log_.AddEvent( 678 net_log_.AddEvent(
674 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, 679 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
675 NetLog::IntegerCallback("attempt_number", attempt_number_)); 680 NetLog::IntegerCallback("attempt_number", attempt_number_));
676 681
677 // If we don't get the results within a given time, RetryIfNotComplete 682 // If we don't get the results within a given time, RetryIfNotComplete
678 // will start a new attempt on a different worker thread if none of our 683 // will start a new attempt on a different worker thread if none of our
679 // outstanding attempts have completed yet. 684 // outstanding attempts have completed yet.
680 if (attempt_number_ <= params_.max_retry_attempts) { 685 if (attempt_number_ <= params_.max_retry_attempts) {
681 origin_loop_->PostDelayedTask( 686 task_runner_->PostDelayedTask(
682 FROM_HERE, 687 FROM_HERE,
683 base::Bind(&ProcTask::RetryIfNotComplete, this), 688 base::Bind(&ProcTask::RetryIfNotComplete, this),
684 params_.unresponsive_delay); 689 params_.unresponsive_delay);
685 } 690 }
686 } 691 }
687 692
688 // WARNING: This code runs inside a worker pool. The shutdown code cannot 693 // WARNING: This code runs inside a worker pool. The shutdown code cannot
689 // wait for it to finish, so we must be very careful here about using other 694 // wait for it to finish, so we must be very careful here about using other
690 // objects (like MessageLoops, Singletons, etc). During shutdown these objects 695 // objects (like MessageLoops, Singletons, etc). During shutdown these objects
691 // may no longer exist. Multiple DoLookups() could be running in parallel, so 696 // may no longer exist. Multiple DoLookups() could be running in parallel, so
(...skipping 13 matching lines...) Expand all
705 // block of kIcanNameCollisionIp for details on why. 710 // block of kIcanNameCollisionIp for details on why.
706 for (const auto& it : results) { 711 for (const auto& it : results) {
707 const IPAddressNumber& cur = it.address(); 712 const IPAddressNumber& cur = it.address();
708 if (cur.size() == arraysize(kIcanNameCollisionIp) && 713 if (cur.size() == arraysize(kIcanNameCollisionIp) &&
709 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) { 714 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) {
710 error = ERR_ICANN_NAME_COLLISION; 715 error = ERR_ICANN_NAME_COLLISION;
711 break; 716 break;
712 } 717 }
713 } 718 }
714 719
715 origin_loop_->PostTask( 720 task_runner_->PostTask(FROM_HERE,
716 FROM_HERE, 721 base::Bind(&ProcTask::OnLookupComplete,
717 base::Bind(&ProcTask::OnLookupComplete, this, results, start_time, 722 this,
718 attempt_number, error, os_error)); 723 results,
724 start_time,
725 attempt_number,
726 error,
727 os_error));
719 } 728 }
720 729
721 // Makes next attempt if DoLookup() has not finished (runs on origin thread). 730 // Makes next attempt if DoLookup() has not finished (runs on task runner
731 // thread).
722 void RetryIfNotComplete() { 732 void RetryIfNotComplete() {
723 DCHECK(origin_loop_->BelongsToCurrentThread()); 733 DCHECK(task_runner_->BelongsToCurrentThread());
724 734
725 if (was_completed() || was_canceled()) 735 if (was_completed() || was_canceled())
726 return; 736 return;
727 737
728 params_.unresponsive_delay *= params_.retry_factor; 738 params_.unresponsive_delay *= params_.retry_factor;
729 StartLookupAttempt(); 739 StartLookupAttempt();
730 } 740 }
731 741
732 // Callback for when DoLookup() completes (runs on origin thread). 742 // Callback for when DoLookup() completes (runs on task runner thread).
733 void OnLookupComplete(const AddressList& results, 743 void OnLookupComplete(const AddressList& results,
734 const base::TimeTicks& start_time, 744 const base::TimeTicks& start_time,
735 const uint32 attempt_number, 745 const uint32 attempt_number,
736 int error, 746 int error,
737 const int os_error) { 747 const int os_error) {
738 DCHECK(origin_loop_->BelongsToCurrentThread()); 748 DCHECK(task_runner_->BelongsToCurrentThread());
739 // If results are empty, we should return an error. 749 // If results are empty, we should return an error.
740 bool empty_list_on_ok = (error == OK && results.empty()); 750 bool empty_list_on_ok = (error == OK && results.empty());
741 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); 751 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok);
742 if (empty_list_on_ok) 752 if (empty_list_on_ok)
743 error = ERR_NAME_NOT_RESOLVED; 753 error = ERR_NAME_NOT_RESOLVED;
744 754
745 bool was_retry_attempt = attempt_number > 1; 755 bool was_retry_attempt = attempt_number > 1;
746 756
747 // Ideally the following code would be part of host_resolver_proc.cc, 757 // Ideally the following code would be part of host_resolver_proc.cc,
748 // however it isn't safe to call NetworkChangeNotifier from worker threads. 758 // however it isn't safe to call NetworkChangeNotifier from worker threads.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 } 805 }
796 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, 806 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK,
797 net_log_callback); 807 net_log_callback);
798 808
799 callback_.Run(error, results_); 809 callback_.Run(error, results_);
800 } 810 }
801 811
802 void RecordPerformanceHistograms(const base::TimeTicks& start_time, 812 void RecordPerformanceHistograms(const base::TimeTicks& start_time,
803 const int error, 813 const int error,
804 const int os_error) const { 814 const int os_error) const {
805 DCHECK(origin_loop_->BelongsToCurrentThread()); 815 DCHECK(task_runner_->BelongsToCurrentThread());
806 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. 816 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION.
807 RESOLVE_SUCCESS, 817 RESOLVE_SUCCESS,
808 RESOLVE_FAIL, 818 RESOLVE_FAIL,
809 RESOLVE_SPECULATIVE_SUCCESS, 819 RESOLVE_SPECULATIVE_SUCCESS,
810 RESOLVE_SPECULATIVE_FAIL, 820 RESOLVE_SPECULATIVE_FAIL,
811 RESOLVE_MAX, // Bounding value. 821 RESOLVE_MAX, // Bounding value.
812 }; 822 };
813 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. 823 int category = RESOLVE_MAX; // Illegal value for later DCHECK only.
814 824
815 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 825 base::TimeDelta duration = base::TimeTicks::Now() - start_time;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 } 872 }
863 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. 873 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set.
864 874
865 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); 875 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX);
866 } 876 }
867 877
868 void RecordAttemptHistograms(const base::TimeTicks& start_time, 878 void RecordAttemptHistograms(const base::TimeTicks& start_time,
869 const uint32 attempt_number, 879 const uint32 attempt_number,
870 const int error, 880 const int error,
871 const int os_error) const { 881 const int os_error) const {
872 DCHECK(origin_loop_->BelongsToCurrentThread()); 882 DCHECK(task_runner_->BelongsToCurrentThread());
873 bool first_attempt_to_complete = 883 bool first_attempt_to_complete =
874 completed_attempt_number_ == attempt_number; 884 completed_attempt_number_ == attempt_number;
875 bool is_first_attempt = (attempt_number == 1); 885 bool is_first_attempt = (attempt_number == 1);
876 886
877 if (first_attempt_to_complete) { 887 if (first_attempt_to_complete) {
878 // If this was first attempt to complete, then record the resolution 888 // If this was first attempt to complete, then record the resolution
879 // status of the attempt. 889 // status of the attempt.
880 if (completed_attempt_error_ == OK) { 890 if (completed_attempt_error_ == OK) {
881 UMA_HISTOGRAM_ENUMERATION( 891 UMA_HISTOGRAM_ENUMERATION(
882 "DNS.AttemptFirstSuccess", attempt_number, 100); 892 "DNS.AttemptFirstSuccess", attempt_number, 100);
(...skipping 26 matching lines...) Expand all
909 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100); 919 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100);
910 } 920 }
911 921
912 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 922 base::TimeDelta duration = base::TimeTicks::Now() - start_time;
913 if (error == OK) 923 if (error == OK)
914 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration); 924 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration);
915 else 925 else
916 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration); 926 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration);
917 } 927 }
918 928
919 // Set on the origin thread, read on the worker thread. 929 // Set on the task runner thread, read on the worker thread.
920 Key key_; 930 Key key_;
921 931
922 // Holds an owning reference to the HostResolverProc that we are going to use. 932 // Holds an owning reference to the HostResolverProc that we are going to use.
923 // This may not be the current resolver procedure by the time we call 933 // This may not be the current resolver procedure by the time we call
924 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning 934 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning
925 // reference ensures that it remains valid until we are done. 935 // reference ensures that it remains valid until we are done.
926 ProcTaskParams params_; 936 ProcTaskParams params_;
927 937
928 // The listener to the results of this ProcTask. 938 // The listener to the results of this ProcTask.
929 Callback callback_; 939 Callback callback_;
930 940
931 // Used to post ourselves onto the origin thread. 941 // Used to post ourselves onto the task runner thread.
932 scoped_refptr<base::MessageLoopProxy> origin_loop_; 942 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
933 943
934 // Keeps track of the number of attempts we have made so far to resolve the 944 // Keeps track of the number of attempts we have made so far to resolve the
935 // host. Whenever we start an attempt to resolve the host, we increase this 945 // host. Whenever we start an attempt to resolve the host, we increase this
936 // number. 946 // number.
937 uint32 attempt_number_; 947 uint32 attempt_number_;
938 948
939 // The index of the attempt which finished first (or 0 if the job is still in 949 // The index of the attempt which finished first (or 0 if the job is still in
940 // progress). 950 // progress).
941 uint32 completed_attempt_number_; 951 uint32 completed_attempt_number_;
942 952
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 void DoProbe() { 994 void DoProbe() {
985 result_ = HaveOnlyLoopbackAddresses(); 995 result_ = HaveOnlyLoopbackAddresses();
986 } 996 }
987 997
988 void OnProbeComplete() { 998 void OnProbeComplete() {
989 if (!resolver_.get()) 999 if (!resolver_.get())
990 return; 1000 return;
991 resolver_->SetHaveOnlyLoopbackAddresses(result_); 1001 resolver_->SetHaveOnlyLoopbackAddresses(result_);
992 } 1002 }
993 1003
994 // Used/set only on origin thread. 1004 // Used/set only on task runner thread.
995 base::WeakPtr<HostResolverImpl> resolver_; 1005 base::WeakPtr<HostResolverImpl> resolver_;
996 1006
997 bool result_; 1007 bool result_;
998 1008
999 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); 1009 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob);
1000 }; 1010 };
1001 1011
1002 //----------------------------------------------------------------------------- 1012 //-----------------------------------------------------------------------------
1003 1013
1004 // Resolves the hostname using DnsTransaction. 1014 // Resolves the hostname using DnsTransaction.
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 dns_client_->SetConfig(dns_config); 2434 dns_client_->SetConfig(dns_config);
2425 num_dns_failures_ = 0; 2435 num_dns_failures_ = 0;
2426 if (dns_client_->GetConfig()) 2436 if (dns_client_->GetConfig())
2427 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2437 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2428 } 2438 }
2429 2439
2430 AbortDnsTasks(); 2440 AbortDnsTasks();
2431 } 2441 }
2432 2442
2433 } // namespace net 2443 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/dns/serial_worker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698