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

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 comments 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') | net/dns/serial_worker.h » ('J')
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.h" 25 #include "base/metrics/histogram.h"
27 #include "base/profiler/scoped_tracker.h" 26 #include "base/profiler/scoped_tracker.h"
27 #include "base/single_thread_task_runner.h"
28 #include "base/stl_util.h" 28 #include "base/stl_util.h"
29 #include "base/strings/string_util.h" 29 #include "base/strings/string_util.h"
30 #include "base/strings/utf_string_conversions.h" 30 #include "base/strings/utf_string_conversions.h"
31 #include "base/thread_task_runner_handle.h"
31 #include "base/threading/worker_pool.h" 32 #include "base/threading/worker_pool.h"
32 #include "base/time/time.h" 33 #include "base/time/time.h"
33 #include "base/values.h" 34 #include "base/values.h"
34 #include "net/base/address_family.h" 35 #include "net/base/address_family.h"
35 #include "net/base/address_list.h" 36 #include "net/base/address_list.h"
36 #include "net/base/dns_reloader.h" 37 #include "net/base/dns_reloader.h"
37 #include "net/base/dns_util.h" 38 #include "net/base/dns_util.h"
38 #include "net/base/host_port_pair.h" 39 #include "net/base/host_port_pair.h"
39 #include "net/base/ip_endpoint.h" 40 #include "net/base/ip_endpoint.h"
40 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 typedef base::Callback<void(int net_error, 567 typedef base::Callback<void(int net_error,
567 const AddressList& addr_list)> Callback; 568 const AddressList& addr_list)> Callback;
568 569
569 ProcTask(const Key& key, 570 ProcTask(const Key& key,
570 const ProcTaskParams& params, 571 const ProcTaskParams& params,
571 const Callback& callback, 572 const Callback& callback,
572 const BoundNetLog& job_net_log) 573 const BoundNetLog& job_net_log)
573 : key_(key), 574 : key_(key),
574 params_(params), 575 params_(params),
575 callback_(callback), 576 callback_(callback),
576 origin_loop_(base::MessageLoopProxy::current()), 577 task_runner_(base::ThreadTaskRunnerHandle::Get()),
577 attempt_number_(0), 578 attempt_number_(0),
578 completed_attempt_number_(0), 579 completed_attempt_number_(0),
579 completed_attempt_error_(ERR_UNEXPECTED), 580 completed_attempt_error_(ERR_UNEXPECTED),
580 had_non_speculative_request_(false), 581 had_non_speculative_request_(false),
581 net_log_(job_net_log) { 582 net_log_(job_net_log) {
582 if (!params_.resolver_proc.get()) 583 if (!params_.resolver_proc.get())
583 params_.resolver_proc = HostResolverProc::GetDefault(); 584 params_.resolver_proc = HostResolverProc::GetDefault();
584 // If default is unset, use the system proc. 585 // If default is unset, use the system proc.
585 if (!params_.resolver_proc.get()) 586 if (!params_.resolver_proc.get())
586 params_.resolver_proc = new SystemHostResolverProc(); 587 params_.resolver_proc = new SystemHostResolverProc();
587 } 588 }
588 589
589 void Start() { 590 void Start() {
590 DCHECK(origin_loop_->BelongsToCurrentThread()); 591 DCHECK(task_runner_->BelongsToCurrentThread());
591 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 592 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
592 StartLookupAttempt(); 593 StartLookupAttempt();
593 } 594 }
594 595
595 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve 596 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve
596 // attempts running on worker threads will continue running. Only once all the 597 // attempts running on worker threads will continue running. Only once all the
597 // attempts complete will the final reference to this ProcTask be released. 598 // attempts complete will the final reference to this ProcTask be released.
598 void Cancel() { 599 void Cancel() {
599 DCHECK(origin_loop_->BelongsToCurrentThread()); 600 DCHECK(task_runner_->BelongsToCurrentThread());
600 601
601 if (was_canceled() || was_completed()) 602 if (was_canceled() || was_completed())
602 return; 603 return;
603 604
604 callback_.Reset(); 605 callback_.Reset();
605 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 606 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
606 } 607 }
607 608
608 void set_had_non_speculative_request() { 609 void set_had_non_speculative_request() {
609 DCHECK(origin_loop_->BelongsToCurrentThread()); 610 DCHECK(task_runner_->BelongsToCurrentThread());
610 had_non_speculative_request_ = true; 611 had_non_speculative_request_ = true;
611 } 612 }
612 613
613 bool was_canceled() const { 614 bool was_canceled() const {
614 DCHECK(origin_loop_->BelongsToCurrentThread()); 615 DCHECK(task_runner_->BelongsToCurrentThread());
615 return callback_.is_null(); 616 return callback_.is_null();
616 } 617 }
617 618
618 bool was_completed() const { 619 bool was_completed() const {
619 DCHECK(origin_loop_->BelongsToCurrentThread()); 620 DCHECK(task_runner_->BelongsToCurrentThread());
620 return completed_attempt_number_ > 0; 621 return completed_attempt_number_ > 0;
621 } 622 }
622 623
623 private: 624 private:
624 friend class base::RefCountedThreadSafe<ProcTask>; 625 friend class base::RefCountedThreadSafe<ProcTask>;
625 ~ProcTask() {} 626 ~ProcTask() {}
626 627
627 void StartLookupAttempt() { 628 void StartLookupAttempt() {
628 DCHECK(origin_loop_->BelongsToCurrentThread()); 629 DCHECK(task_runner_->BelongsToCurrentThread());
629 base::TimeTicks start_time = base::TimeTicks::Now(); 630 base::TimeTicks start_time = base::TimeTicks::Now();
630 ++attempt_number_; 631 ++attempt_number_;
631 // Dispatch the lookup attempt to a worker thread. 632 // Dispatch the lookup attempt to a worker thread.
632 if (!base::WorkerPool::PostTask( 633 if (!base::WorkerPool::PostTask(
633 FROM_HERE, 634 FROM_HERE,
634 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), 635 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_),
635 true)) { 636 true)) {
636 NOTREACHED(); 637 NOTREACHED();
637 638
638 // Since we could be running within Resolve() right now, we can't just 639 // Since we could be running within Resolve() right now, we can't just
639 // call OnLookupComplete(). Instead we must wait until Resolve() has 640 // call OnLookupComplete(). Instead we must wait until Resolve() has
640 // returned (IO_PENDING). 641 // returned (IO_PENDING).
641 origin_loop_->PostTask( 642 task_runner_->PostTask(FROM_HERE,
642 FROM_HERE, 643 base::Bind(&ProcTask::OnLookupComplete,
643 base::Bind(&ProcTask::OnLookupComplete, this, AddressList(), 644 this,
644 start_time, attempt_number_, ERR_UNEXPECTED, 0)); 645 AddressList(),
646 start_time,
647 attempt_number_,
648 ERR_UNEXPECTED,
649 0));
645 return; 650 return;
646 } 651 }
647 652
648 net_log_.AddEvent( 653 net_log_.AddEvent(
649 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, 654 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
650 NetLog::IntegerCallback("attempt_number", attempt_number_)); 655 NetLog::IntegerCallback("attempt_number", attempt_number_));
651 656
652 // If we don't get the results within a given time, RetryIfNotComplete 657 // If we don't get the results within a given time, RetryIfNotComplete
653 // will start a new attempt on a different worker thread if none of our 658 // will start a new attempt on a different worker thread if none of our
654 // outstanding attempts have completed yet. 659 // outstanding attempts have completed yet.
655 if (attempt_number_ <= params_.max_retry_attempts) { 660 if (attempt_number_ <= params_.max_retry_attempts) {
656 origin_loop_->PostDelayedTask( 661 task_runner_->PostDelayedTask(
657 FROM_HERE, 662 FROM_HERE,
658 base::Bind(&ProcTask::RetryIfNotComplete, this), 663 base::Bind(&ProcTask::RetryIfNotComplete, this),
659 params_.unresponsive_delay); 664 params_.unresponsive_delay);
660 } 665 }
661 } 666 }
662 667
663 // WARNING: This code runs inside a worker pool. The shutdown code cannot 668 // WARNING: This code runs inside a worker pool. The shutdown code cannot
664 // wait for it to finish, so we must be very careful here about using other 669 // wait for it to finish, so we must be very careful here about using other
665 // objects (like MessageLoops, Singletons, etc). During shutdown these objects 670 // objects (like MessageLoops, Singletons, etc). During shutdown these objects
666 // may no longer exist. Multiple DoLookups() could be running in parallel, so 671 // may no longer exist. Multiple DoLookups() could be running in parallel, so
(...skipping 13 matching lines...) Expand all
680 // block of kIcanNameCollisionIp for details on why. 685 // block of kIcanNameCollisionIp for details on why.
681 for (const auto& it : results) { 686 for (const auto& it : results) {
682 const IPAddressNumber& cur = it.address(); 687 const IPAddressNumber& cur = it.address();
683 if (cur.size() == arraysize(kIcanNameCollisionIp) && 688 if (cur.size() == arraysize(kIcanNameCollisionIp) &&
684 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) { 689 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) {
685 error = ERR_ICANN_NAME_COLLISION; 690 error = ERR_ICANN_NAME_COLLISION;
686 break; 691 break;
687 } 692 }
688 } 693 }
689 694
690 origin_loop_->PostTask( 695 task_runner_->PostTask(FROM_HERE,
691 FROM_HERE, 696 base::Bind(&ProcTask::OnLookupComplete,
692 base::Bind(&ProcTask::OnLookupComplete, this, results, start_time, 697 this,
693 attempt_number, error, os_error)); 698 results,
699 start_time,
700 attempt_number,
701 error,
702 os_error));
694 } 703 }
695 704
696 // Makes next attempt if DoLookup() has not finished (runs on origin thread). 705 // Makes next attempt if DoLookup() has not finished (runs on task runner
706 // thread).
697 void RetryIfNotComplete() { 707 void RetryIfNotComplete() {
698 DCHECK(origin_loop_->BelongsToCurrentThread()); 708 DCHECK(task_runner_->BelongsToCurrentThread());
699 709
700 if (was_completed() || was_canceled()) 710 if (was_completed() || was_canceled())
701 return; 711 return;
702 712
703 params_.unresponsive_delay *= params_.retry_factor; 713 params_.unresponsive_delay *= params_.retry_factor;
704 StartLookupAttempt(); 714 StartLookupAttempt();
705 } 715 }
706 716
707 // Callback for when DoLookup() completes (runs on origin thread). 717 // Callback for when DoLookup() completes (runs on task runner thread).
708 void OnLookupComplete(const AddressList& results, 718 void OnLookupComplete(const AddressList& results,
709 const base::TimeTicks& start_time, 719 const base::TimeTicks& start_time,
710 const uint32 attempt_number, 720 const uint32 attempt_number,
711 int error, 721 int error,
712 const int os_error) { 722 const int os_error) {
713 DCHECK(origin_loop_->BelongsToCurrentThread()); 723 DCHECK(task_runner_->BelongsToCurrentThread());
714 // If results are empty, we should return an error. 724 // If results are empty, we should return an error.
715 bool empty_list_on_ok = (error == OK && results.empty()); 725 bool empty_list_on_ok = (error == OK && results.empty());
716 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); 726 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok);
717 if (empty_list_on_ok) 727 if (empty_list_on_ok)
718 error = ERR_NAME_NOT_RESOLVED; 728 error = ERR_NAME_NOT_RESOLVED;
719 729
720 bool was_retry_attempt = attempt_number > 1; 730 bool was_retry_attempt = attempt_number > 1;
721 731
722 // Ideally the following code would be part of host_resolver_proc.cc, 732 // Ideally the following code would be part of host_resolver_proc.cc,
723 // however it isn't safe to call NetworkChangeNotifier from worker threads. 733 // however it isn't safe to call NetworkChangeNotifier from worker threads.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 } 780 }
771 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, 781 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK,
772 net_log_callback); 782 net_log_callback);
773 783
774 callback_.Run(error, results_); 784 callback_.Run(error, results_);
775 } 785 }
776 786
777 void RecordPerformanceHistograms(const base::TimeTicks& start_time, 787 void RecordPerformanceHistograms(const base::TimeTicks& start_time,
778 const int error, 788 const int error,
779 const int os_error) const { 789 const int os_error) const {
780 DCHECK(origin_loop_->BelongsToCurrentThread()); 790 DCHECK(task_runner_->BelongsToCurrentThread());
781 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. 791 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION.
782 RESOLVE_SUCCESS, 792 RESOLVE_SUCCESS,
783 RESOLVE_FAIL, 793 RESOLVE_FAIL,
784 RESOLVE_SPECULATIVE_SUCCESS, 794 RESOLVE_SPECULATIVE_SUCCESS,
785 RESOLVE_SPECULATIVE_FAIL, 795 RESOLVE_SPECULATIVE_FAIL,
786 RESOLVE_MAX, // Bounding value. 796 RESOLVE_MAX, // Bounding value.
787 }; 797 };
788 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. 798 int category = RESOLVE_MAX; // Illegal value for later DCHECK only.
789 799
790 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 800 base::TimeDelta duration = base::TimeTicks::Now() - start_time;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 } 847 }
838 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. 848 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set.
839 849
840 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); 850 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX);
841 } 851 }
842 852
843 void RecordAttemptHistograms(const base::TimeTicks& start_time, 853 void RecordAttemptHistograms(const base::TimeTicks& start_time,
844 const uint32 attempt_number, 854 const uint32 attempt_number,
845 const int error, 855 const int error,
846 const int os_error) const { 856 const int os_error) const {
847 DCHECK(origin_loop_->BelongsToCurrentThread()); 857 DCHECK(task_runner_->BelongsToCurrentThread());
848 bool first_attempt_to_complete = 858 bool first_attempt_to_complete =
849 completed_attempt_number_ == attempt_number; 859 completed_attempt_number_ == attempt_number;
850 bool is_first_attempt = (attempt_number == 1); 860 bool is_first_attempt = (attempt_number == 1);
851 861
852 if (first_attempt_to_complete) { 862 if (first_attempt_to_complete) {
853 // If this was first attempt to complete, then record the resolution 863 // If this was first attempt to complete, then record the resolution
854 // status of the attempt. 864 // status of the attempt.
855 if (completed_attempt_error_ == OK) { 865 if (completed_attempt_error_ == OK) {
856 UMA_HISTOGRAM_ENUMERATION( 866 UMA_HISTOGRAM_ENUMERATION(
857 "DNS.AttemptFirstSuccess", attempt_number, 100); 867 "DNS.AttemptFirstSuccess", attempt_number, 100);
(...skipping 26 matching lines...) Expand all
884 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100); 894 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100);
885 } 895 }
886 896
887 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 897 base::TimeDelta duration = base::TimeTicks::Now() - start_time;
888 if (error == OK) 898 if (error == OK)
889 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration); 899 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration);
890 else 900 else
891 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration); 901 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration);
892 } 902 }
893 903
894 // Set on the origin thread, read on the worker thread. 904 // Set on the task runner thread, read on the worker thread.
895 Key key_; 905 Key key_;
896 906
897 // Holds an owning reference to the HostResolverProc that we are going to use. 907 // Holds an owning reference to the HostResolverProc that we are going to use.
898 // This may not be the current resolver procedure by the time we call 908 // This may not be the current resolver procedure by the time we call
899 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning 909 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning
900 // reference ensures that it remains valid until we are done. 910 // reference ensures that it remains valid until we are done.
901 ProcTaskParams params_; 911 ProcTaskParams params_;
902 912
903 // The listener to the results of this ProcTask. 913 // The listener to the results of this ProcTask.
904 Callback callback_; 914 Callback callback_;
905 915
906 // Used to post ourselves onto the origin thread. 916 // Used to post ourselves onto the task runner thread.
asanka 2015/05/14 18:38:40 .. on to the originating thread.
anujsharma 2015/05/20 13:13:16 Done.
907 scoped_refptr<base::MessageLoopProxy> origin_loop_; 917 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
908 918
909 // Keeps track of the number of attempts we have made so far to resolve the 919 // Keeps track of the number of attempts we have made so far to resolve the
910 // host. Whenever we start an attempt to resolve the host, we increase this 920 // host. Whenever we start an attempt to resolve the host, we increase this
911 // number. 921 // number.
912 uint32 attempt_number_; 922 uint32 attempt_number_;
913 923
914 // The index of the attempt which finished first (or 0 if the job is still in 924 // The index of the attempt which finished first (or 0 if the job is still in
915 // progress). 925 // progress).
916 uint32 completed_attempt_number_; 926 uint32 completed_attempt_number_;
917 927
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 void DoProbe() { 969 void DoProbe() {
960 result_ = HaveOnlyLoopbackAddresses(); 970 result_ = HaveOnlyLoopbackAddresses();
961 } 971 }
962 972
963 void OnProbeComplete() { 973 void OnProbeComplete() {
964 if (!resolver_.get()) 974 if (!resolver_.get())
965 return; 975 return;
966 resolver_->SetHaveOnlyLoopbackAddresses(result_); 976 resolver_->SetHaveOnlyLoopbackAddresses(result_);
967 } 977 }
968 978
969 // Used/set only on origin thread. 979 // Used/set only on task runner thread.
970 base::WeakPtr<HostResolverImpl> resolver_; 980 base::WeakPtr<HostResolverImpl> resolver_;
971 981
972 bool result_; 982 bool result_;
973 983
974 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); 984 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob);
975 }; 985 };
976 986
977 //----------------------------------------------------------------------------- 987 //-----------------------------------------------------------------------------
978 988
979 // Resolves the hostname using DnsTransaction. 989 // Resolves the hostname using DnsTransaction.
(...skipping 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 dns_client_->SetConfig(dns_config); 2402 dns_client_->SetConfig(dns_config);
2393 num_dns_failures_ = 0; 2403 num_dns_failures_ = 0;
2394 if (dns_client_->GetConfig()) 2404 if (dns_client_->GetConfig())
2395 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2405 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2396 } 2406 }
2397 2407
2398 AbortDnsTasks(); 2408 AbortDnsTasks();
2399 } 2409 }
2400 2410
2401 } // namespace net 2411 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/dns/serial_worker.h » ('j') | net/dns/serial_worker.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698