| 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 "chrome/browser/net/predictor.h" | 5 #include "chrome/browser/net/predictor.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 static int g_max_queueing_delay_ms = | 98 static int g_max_queueing_delay_ms = |
| 99 Predictor::kMaxSpeculativeResolveQueueDelayMs; | 99 Predictor::kMaxSpeculativeResolveQueueDelayMs; |
| 100 static size_t g_max_parallel_resolves = | 100 static size_t g_max_parallel_resolves = |
| 101 Predictor::kMaxSpeculativeParallelResolves; | 101 Predictor::kMaxSpeculativeParallelResolves; |
| 102 | 102 |
| 103 // A version number for prefs that are saved. This should be incremented when | 103 // A version number for prefs that are saved. This should be incremented when |
| 104 // we change the format so that we discard old data. | 104 // we change the format so that we discard old data. |
| 105 static const int kPredictorStartupFormatVersion = 1; | 105 static const int kPredictorStartupFormatVersion = 1; |
| 106 | 106 |
| 107 class Predictor::LookupRequest { | |
| 108 public: | |
| 109 LookupRequest(Predictor* predictor, | |
| 110 net::HostResolver* host_resolver, | |
| 111 const GURL& url) | |
| 112 : predictor_(predictor), | |
| 113 url_(url), | |
| 114 resolver_(host_resolver) { | |
| 115 } | |
| 116 | |
| 117 // Return underlying network resolver status. | |
| 118 // net::OK ==> Host was found synchronously. | |
| 119 // net:ERR_IO_PENDING ==> Network will callback later with result. | |
| 120 // anything else ==> Host was not found synchronously. | |
| 121 int Start() { | |
| 122 net::HostResolver::RequestInfo resolve_info( | |
| 123 net::HostPortPair::FromURL(url_)); | |
| 124 | |
| 125 // Make a note that this is a speculative resolve request. This allows us | |
| 126 // to separate it from real navigations in the observer's callback, and | |
| 127 // lets the HostResolver know it can de-prioritize it. | |
| 128 resolve_info.set_is_speculative(true); | |
| 129 return resolver_.Resolve( | |
| 130 resolve_info, | |
| 131 net::DEFAULT_PRIORITY, | |
| 132 &addresses_, | |
| 133 base::Bind(&LookupRequest::OnLookupFinished, base::Unretained(this)), | |
| 134 net::BoundNetLog()); | |
| 135 } | |
| 136 | |
| 137 private: | |
| 138 void OnLookupFinished(int result) { | |
| 139 predictor_->OnLookupFinished(this, url_, result == net::OK); | |
| 140 } | |
| 141 | |
| 142 Predictor* predictor_; // The predictor which started us. | |
| 143 | |
| 144 const GURL url_; // Hostname to resolve. | |
| 145 net::SingleRequestHostResolver resolver_; | |
| 146 net::AddressList addresses_; | |
| 147 | |
| 148 DISALLOW_COPY_AND_ASSIGN(LookupRequest); | |
| 149 }; | |
| 150 | |
| 151 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) | 107 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) |
| 152 : url_request_context_getter_(NULL), | 108 : url_request_context_getter_(nullptr), |
| 153 predictor_enabled_(predictor_enabled), | 109 predictor_enabled_(predictor_enabled), |
| 154 user_prefs_(NULL), | 110 user_prefs_(nullptr), |
| 155 profile_io_data_(NULL), | 111 profile_io_data_(nullptr), |
| 112 num_pending_lookups_(0), |
| 156 peak_pending_lookups_(0), | 113 peak_pending_lookups_(0), |
| 157 shutdown_(false), | 114 shutdown_(false), |
| 158 max_concurrent_dns_lookups_(g_max_parallel_resolves), | 115 max_concurrent_dns_lookups_(g_max_parallel_resolves), |
| 159 max_dns_queue_delay_( | 116 max_dns_queue_delay_( |
| 160 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), | 117 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), |
| 161 host_resolver_(NULL), | 118 transport_security_state_(nullptr), |
| 162 transport_security_state_(NULL), | 119 ssl_config_service_(nullptr), |
| 163 ssl_config_service_(NULL), | 120 proxy_service_(nullptr), |
| 164 proxy_service_(NULL), | |
| 165 preconnect_enabled_(preconnect_enabled), | 121 preconnect_enabled_(preconnect_enabled), |
| 166 consecutive_omnibox_preconnect_count_(0), | 122 consecutive_omnibox_preconnect_count_(0), |
| 167 next_trim_time_(base::TimeTicks::Now() + | 123 next_trim_time_(base::TimeTicks::Now() + |
| 168 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), | 124 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), |
| 169 observer_(NULL), | 125 observer_(nullptr), |
| 170 timed_cache_(new TimedCache(base::TimeDelta::FromSeconds( | 126 timed_cache_(new TimedCache(base::TimeDelta::FromSeconds( |
| 171 kMaxUnusedSocketLifetimeSecondsWithoutAGet))) { | 127 kMaxUnusedSocketLifetimeSecondsWithoutAGet))) { |
| 172 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 128 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 173 } | 129 } |
| 174 | 130 |
| 175 Predictor::~Predictor() { | 131 Predictor::~Predictor() { |
| 176 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 132 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 177 DCHECK(shutdown_); | 133 DCHECK(shutdown_); |
| 178 } | 134 } |
| 179 | 135 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 } | 349 } |
| 394 | 350 |
| 395 // ---------------------- End UI methods. ------------------------------------- | 351 // ---------------------- End UI methods. ------------------------------------- |
| 396 | 352 |
| 397 // --------------------- Start IO methods. ------------------------------------ | 353 // --------------------- Start IO methods. ------------------------------------ |
| 398 | 354 |
| 399 void Predictor::Shutdown() { | 355 void Predictor::Shutdown() { |
| 400 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 356 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 401 DCHECK(!shutdown_); | 357 DCHECK(!shutdown_); |
| 402 shutdown_ = true; | 358 shutdown_ = true; |
| 403 | |
| 404 STLDeleteElements(&pending_lookups_); | |
| 405 } | 359 } |
| 406 | 360 |
| 407 void Predictor::DiscardAllResults() { | 361 void Predictor::DiscardAllResults() { |
| 408 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 362 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 409 // Delete anything listed so far in this session that shows in about:dns. | 363 // Delete anything listed so far in this session that shows in about:dns. |
| 410 referrers_.clear(); | 364 referrers_.clear(); |
| 411 | 365 |
| 412 | 366 |
| 413 // Try to delete anything in our work queue. | 367 // Try to delete anything in our work queue. |
| 414 while (!work_queue_.IsEmpty()) { | 368 while (!work_queue_.IsEmpty()) { |
| 415 // Emulate processing cycle as though host was not found. | 369 // Emulate processing cycle as though host was not found. |
| 416 GURL url = work_queue_.Pop(); | 370 GURL url = work_queue_.Pop(); |
| 417 UrlInfo* info = &results_[url]; | 371 UrlInfo* info = &results_[url]; |
| 418 DCHECK(info->HasUrl(url)); | 372 DCHECK(info->HasUrl(url)); |
| 419 info->SetAssignedState(); | 373 info->SetAssignedState(); |
| 420 info->SetNoSuchNameState(); | 374 info->SetNoSuchNameState(); |
| 421 } | 375 } |
| 422 // Now every result_ is either resolved, or is being resolved | 376 // Now every result_ is either resolved, or is being resolved. |
| 423 // (see LookupRequest). | |
| 424 | 377 |
| 425 // Step through result_, recording names of all hosts that can't be erased. | 378 // Step through result_, recording names of all hosts that can't be erased. |
| 426 // We can't erase anything being worked on. | 379 // We can't erase anything being worked on. |
| 427 Results assignees; | 380 Results assignees; |
| 428 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) { | 381 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) { |
| 429 GURL url(it->first); | 382 GURL url(it->first); |
| 430 UrlInfo* info = &it->second; | 383 UrlInfo* info = &it->second; |
| 431 DCHECK(info->HasUrl(url)); | 384 DCHECK(info->HasUrl(url)); |
| 432 if (info->is_assigned()) { | 385 if (info->is_assigned()) { |
| 433 info->SetPendingDeleteState(); | 386 info->SetPendingDeleteState(); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 | 641 |
| 689 void Predictor::FinalizeInitializationOnIOThread( | 642 void Predictor::FinalizeInitializationOnIOThread( |
| 690 const UrlList& startup_urls, | 643 const UrlList& startup_urls, |
| 691 base::ListValue* referral_list, | 644 base::ListValue* referral_list, |
| 692 IOThread* io_thread, | 645 IOThread* io_thread, |
| 693 ProfileIOData* profile_io_data) { | 646 ProfileIOData* profile_io_data) { |
| 694 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 647 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 695 | 648 |
| 696 profile_io_data_ = profile_io_data; | 649 profile_io_data_ = profile_io_data; |
| 697 initial_observer_.reset(new InitialObserver()); | 650 initial_observer_.reset(new InitialObserver()); |
| 698 host_resolver_ = io_thread->globals()->host_resolver.get(); | |
| 699 | 651 |
| 700 net::URLRequestContext* context = | 652 net::URLRequestContext* context = |
| 701 url_request_context_getter_->GetURLRequestContext(); | 653 url_request_context_getter_->GetURLRequestContext(); |
| 702 transport_security_state_ = context->transport_security_state(); | 654 transport_security_state_ = context->transport_security_state(); |
| 703 ssl_config_service_ = context->ssl_config_service(); | 655 ssl_config_service_ = context->ssl_config_service(); |
| 704 proxy_service_ = context->proxy_service(); | 656 proxy_service_ = context->proxy_service(); |
| 705 | 657 |
| 706 // base::WeakPtrFactory instances need to be created and destroyed | 658 // base::WeakPtrFactory instances need to be created and destroyed |
| 707 // on the same thread. The predictor lives on the IO thread and will die | 659 // on the same thread. The predictor lives on the IO thread and will die |
| 708 // from there so now that we're on the IO thread we need to properly | 660 // from there so now that we're on the IO thread we need to properly |
| 709 // initialize the base::WeakPtrFactory. | 661 // initialize the base::WeakPtrFactory. |
| 710 // TODO(groby): Check if WeakPtrFactory has the same constraint. | 662 // TODO(groby): Check if WeakPtrFactory has the same constraint. |
| 711 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); | 663 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| 712 | 664 |
| 713 // Prefetch these hostnames on startup. | 665 // Prefetch these hostnames on startup. |
| 714 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); | 666 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| 715 | 667 |
| 716 DeserializeReferrersThenDelete(referral_list); | 668 DeserializeReferrersThenDelete(referral_list); |
| 717 } | 669 } |
| 718 | 670 |
| 719 //----------------------------------------------------------------------------- | 671 //----------------------------------------------------------------------------- |
| 720 // This section intermingles prefetch results with actual browser HTTP | 672 // This section intermingles prefetch results with actual browser HTTP |
| 721 // network activity. It supports calculating of the benefit of a prefetch, as | 673 // network activity. It supports calculating of the benefit of a prefetch, as |
| 722 // well as recording what prefetched hostname resolutions might be potentially | 674 // well as recording what prefetched hostname resolutions might be potentially |
| 723 // helpful during the next chrome-startup. | 675 // helpful during the next chrome-startup. |
| 724 //----------------------------------------------------------------------------- | 676 //----------------------------------------------------------------------------- |
| 725 | 677 |
| 726 void Predictor::LearnAboutInitialNavigation(const GURL& url) { | 678 void Predictor::LearnAboutInitialNavigation(const GURL& url) { |
| 727 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 679 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 728 if (!predictor_enabled_ || NULL == initial_observer_.get() || | 680 if (!predictor_enabled_ || nullptr == initial_observer_.get() || |
| 729 !CanPreresolveAndPreconnect()) { | 681 !CanPreresolveAndPreconnect()) { |
| 730 return; | 682 return; |
| 731 } | 683 } |
| 732 initial_observer_->Append(url, this); | 684 initial_observer_->Append(url, this); |
| 733 } | 685 } |
| 734 | 686 |
| 735 // This API is only used in the browser process. | 687 // This API is only used in the browser process. |
| 736 // It is called from an IPC message originating in the renderer. It currently | 688 // It is called from an IPC message originating in the renderer. It currently |
| 737 // includes both Page-Scan, and Link-Hover prefetching. | 689 // includes both Page-Scan, and Link-Hover prefetching. |
| 738 // TODO(jar): Separate out link-hover prefetching, and page-scan results. | 690 // TODO(jar): Separate out link-hover prefetching, and page-scan results. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 // Functions to handle saving of hostnames from one session to the next, to | 727 // Functions to handle saving of hostnames from one session to the next, to |
| 776 // expedite startup times. | 728 // expedite startup times. |
| 777 | 729 |
| 778 static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( | 730 static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( |
| 779 base::ListValue* startup_list, | 731 base::ListValue* startup_list, |
| 780 base::ListValue* referral_list, | 732 base::ListValue* referral_list, |
| 781 base::WaitableEvent* completion, | 733 base::WaitableEvent* completion, |
| 782 Predictor* predictor) { | 734 Predictor* predictor) { |
| 783 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 735 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 784 | 736 |
| 785 if (NULL == predictor) { | 737 if (nullptr == predictor) { |
| 786 completion->Signal(); | 738 completion->Signal(); |
| 787 return; | 739 return; |
| 788 } | 740 } |
| 789 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( | 741 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( |
| 790 startup_list, referral_list, completion); | 742 startup_list, referral_list, completion); |
| 791 } | 743 } |
| 792 | 744 |
| 793 void Predictor::SaveStateForNextStartupAndTrim() { | 745 void Predictor::SaveStateForNextStartupAndTrim() { |
| 794 if (!predictor_enabled_) | 746 if (!predictor_enabled_) |
| 795 return; | 747 return; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 void Predictor::PreconnectUrlOnIOThread( | 823 void Predictor::PreconnectUrlOnIOThread( |
| 872 const GURL& original_url, | 824 const GURL& original_url, |
| 873 const GURL& first_party_for_cookies, | 825 const GURL& first_party_for_cookies, |
| 874 UrlInfo::ResolutionMotivation motivation, | 826 UrlInfo::ResolutionMotivation motivation, |
| 875 bool allow_credentials, | 827 bool allow_credentials, |
| 876 int count) { | 828 int count) { |
| 877 // Skip the HSTS redirect. | 829 // Skip the HSTS redirect. |
| 878 GURL url = GetHSTSRedirectOnIOThread(original_url); | 830 GURL url = GetHSTSRedirectOnIOThread(original_url); |
| 879 | 831 |
| 880 // TODO(csharrison): The observer should only be notified after the null check | 832 // TODO(csharrison): The observer should only be notified after the null check |
| 881 // for the URLRequestContextGetter. The predictor tests should be fixed to | 833 // for the ProfileIOData. The predictor tests should be fixed to allow for |
| 882 // allow for this, as they currently expect a callback with no getter. | 834 // this, as they currently expect a callback with no getter. |
| 883 // URLRequestContextGetter is null. Tests rely on this behavior. | |
| 884 if (observer_) { | 835 if (observer_) { |
| 885 observer_->OnPreconnectUrl( | 836 observer_->OnPreconnectUrl( |
| 886 url, first_party_for_cookies, motivation, count); | 837 url, first_party_for_cookies, motivation, count); |
| 887 } | 838 } |
| 888 | 839 |
| 889 net::URLRequestContextGetter* getter = url_request_context_getter_.get(); | 840 if (!profile_io_data_) |
| 890 if (!getter) | |
| 891 return; | 841 return; |
| 892 | 842 |
| 893 // Translate the motivation from UrlRequest motivations to HttpRequest | 843 // Translate the motivation from UrlRequest motivations to HttpRequest |
| 894 // motivations. | 844 // motivations. |
| 895 net::HttpRequestInfo::RequestMotivation request_motivation = | 845 net::HttpRequestInfo::RequestMotivation request_motivation = |
| 896 net::HttpRequestInfo::NORMAL_MOTIVATION; | 846 net::HttpRequestInfo::NORMAL_MOTIVATION; |
| 897 switch (motivation) { | 847 switch (motivation) { |
| 898 case UrlInfo::OMNIBOX_MOTIVATED: | 848 case UrlInfo::OMNIBOX_MOTIVATED: |
| 899 request_motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; | 849 request_motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; |
| 900 break; | 850 break; |
| 901 case UrlInfo::LEARNED_REFERAL_MOTIVATED: | 851 case UrlInfo::LEARNED_REFERAL_MOTIVATED: |
| 902 request_motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; | 852 request_motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; |
| 903 break; | 853 break; |
| 904 case UrlInfo::MOUSE_OVER_MOTIVATED: | 854 case UrlInfo::MOUSE_OVER_MOTIVATED: |
| 905 case UrlInfo::SELF_REFERAL_MOTIVATED: | 855 case UrlInfo::SELF_REFERAL_MOTIVATED: |
| 906 case UrlInfo::EARLY_LOAD_MOTIVATED: | 856 case UrlInfo::EARLY_LOAD_MOTIVATED: |
| 907 request_motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; | 857 request_motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; |
| 908 break; | 858 break; |
| 909 default: | 859 default: |
| 910 // Other motivations should never happen here. | 860 // Other motivations should never happen here. |
| 911 NOTREACHED(); | 861 NOTREACHED(); |
| 912 break; | 862 break; |
| 913 } | 863 } |
| 914 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation, | 864 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation, |
| 915 UrlInfo::MAX_MOTIVATED); | 865 UrlInfo::MAX_MOTIVATED); |
| 916 content::PreconnectUrl(getter, url, first_party_for_cookies, count, | 866 content::PreconnectUrl(profile_io_data_->GetResourceContext(), url, |
| 917 allow_credentials, request_motivation); | 867 first_party_for_cookies, count, allow_credentials, |
| 868 request_motivation); |
| 918 } | 869 } |
| 919 | 870 |
| 920 void Predictor::PredictFrameSubresources(const GURL& url, | 871 void Predictor::PredictFrameSubresources(const GURL& url, |
| 921 const GURL& first_party_for_cookies) { | 872 const GURL& first_party_for_cookies) { |
| 922 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 873 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 923 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 874 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 924 if (!predictor_enabled_) | 875 if (!predictor_enabled_) |
| 925 return; | 876 return; |
| 926 if (!CanPreresolveAndPreconnect()) | 877 if (!CanPreresolveAndPreconnect()) |
| 927 return; | 878 return; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, | 969 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, |
| 1019 motivation); | 970 motivation); |
| 1020 if (queued_info) | 971 if (queued_info) |
| 1021 queued_info->SetReferringHostname(url); | 972 queued_info->SetReferringHostname(url); |
| 1022 } | 973 } |
| 1023 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, | 974 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, |
| 1024 SUBRESOURCE_VALUE_MAX); | 975 SUBRESOURCE_VALUE_MAX); |
| 1025 } | 976 } |
| 1026 } | 977 } |
| 1027 | 978 |
| 1028 void Predictor::OnLookupFinished(LookupRequest* request, const GURL& url, | 979 void Predictor::OnLookupFinished(const GURL& url, int result) { |
| 1029 bool found) { | |
| 1030 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 980 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1031 | 981 LookupFinished(url, result == net::OK); |
| 1032 LookupFinished(request, url, found); | |
| 1033 if (observer_) | 982 if (observer_) |
| 1034 observer_->OnDnsLookupFinished(url, found); | 983 observer_->OnDnsLookupFinished(url, result == net::OK); |
| 1035 pending_lookups_.erase(request); | 984 DCHECK_GT(num_pending_lookups_, 0u); |
| 1036 delete request; | 985 num_pending_lookups_--; |
| 1037 | |
| 1038 StartSomeQueuedResolutions(); | 986 StartSomeQueuedResolutions(); |
| 1039 } | 987 } |
| 1040 | 988 |
| 1041 void Predictor::LookupFinished(LookupRequest* request, const GURL& url, | 989 void Predictor::LookupFinished(const GURL& url, bool found) { |
| 1042 bool found) { | |
| 1043 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 990 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1044 UrlInfo* info = &results_[url]; | 991 UrlInfo* info = &results_[url]; |
| 1045 DCHECK(info->HasUrl(url)); | 992 DCHECK(info->HasUrl(url)); |
| 1046 if (info->is_marked_to_delete()) { | 993 if (info->is_marked_to_delete()) { |
| 1047 results_.erase(url); | 994 results_.erase(url); |
| 1048 } else { | 995 } else { |
| 1049 if (found) | 996 if (found) |
| 1050 info->SetFoundState(); | 997 info->SetFoundState(); |
| 1051 else | 998 else |
| 1052 info->SetNoSuchNameState(); | 999 info->SetNoSuchNameState(); |
| 1053 } | 1000 } |
| 1054 } | 1001 } |
| 1055 | 1002 |
| 1056 bool Predictor::WouldLikelyProxyURL(const GURL& url) { | 1003 bool Predictor::WouldLikelyProxyURL(const GURL& url) { |
| 1057 if (!proxy_service_) | 1004 if (!proxy_service_) |
| 1058 return false; | 1005 return false; |
| 1059 | 1006 |
| 1060 net::ProxyInfo info; | 1007 net::ProxyInfo info; |
| 1061 bool synchronous_success = proxy_service_->TryResolveProxySynchronously( | 1008 bool synchronous_success = proxy_service_->TryResolveProxySynchronously( |
| 1062 url, std::string(), net::LOAD_NORMAL, &info, NULL, net::BoundNetLog()); | 1009 url, std::string(), net::LOAD_NORMAL, &info, nullptr, net::BoundNetLog()); |
| 1063 | 1010 |
| 1064 return synchronous_success && !info.is_direct(); | 1011 return synchronous_success && !info.is_direct(); |
| 1065 } | 1012 } |
| 1066 | 1013 |
| 1067 UrlInfo* Predictor::AppendToResolutionQueue( | 1014 UrlInfo* Predictor::AppendToResolutionQueue( |
| 1068 const GURL& url, | 1015 const GURL& url, |
| 1069 UrlInfo::ResolutionMotivation motivation) { | 1016 UrlInfo::ResolutionMotivation motivation) { |
| 1070 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1017 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1071 DCHECK(url.has_host()); | 1018 DCHECK(url.has_host()); |
| 1072 | 1019 |
| 1073 if (shutdown_) | 1020 if (shutdown_) |
| 1074 return NULL; | 1021 return nullptr; |
| 1075 | 1022 |
| 1076 UrlInfo* info = &results_[url]; | 1023 UrlInfo* info = &results_[url]; |
| 1077 info->SetUrl(url); // Initialize or DCHECK. | 1024 info->SetUrl(url); // Initialize or DCHECK. |
| 1078 // TODO(jar): I need to discard names that have long since expired. | 1025 // TODO(jar): I need to discard names that have long since expired. |
| 1079 // Currently we only add to the domain map :-/ | 1026 // Currently we only add to the domain map :-/ |
| 1080 | 1027 |
| 1081 DCHECK(info->HasUrl(url)); | 1028 DCHECK(info->HasUrl(url)); |
| 1082 | 1029 |
| 1083 if (!info->NeedsDnsUpdate()) { | 1030 if (!info->NeedsDnsUpdate()) { |
| 1084 info->DLogResultsStats("DNS PrefetchNotUpdated"); | 1031 info->DLogResultsStats("DNS PrefetchNotUpdated"); |
| 1085 return NULL; | 1032 return nullptr; |
| 1086 } | 1033 } |
| 1087 | 1034 |
| 1088 if (WouldLikelyProxyURL(url)) { | 1035 if (WouldLikelyProxyURL(url)) { |
| 1089 info->DLogResultsStats("DNS PrefetchForProxiedRequest"); | 1036 info->DLogResultsStats("DNS PrefetchForProxiedRequest"); |
| 1090 return NULL; | 1037 return nullptr; |
| 1091 } | 1038 } |
| 1092 | 1039 |
| 1093 info->SetQueuedState(motivation); | 1040 info->SetQueuedState(motivation); |
| 1094 work_queue_.Push(url, motivation); | 1041 work_queue_.Push(url, motivation); |
| 1095 | 1042 |
| 1096 StartSomeQueuedResolutions(); | 1043 StartSomeQueuedResolutions(); |
| 1097 return info; | 1044 return info; |
| 1098 } | 1045 } |
| 1099 | 1046 |
| 1100 bool Predictor::CongestionControlPerformed(UrlInfo* info) { | 1047 bool Predictor::CongestionControlPerformed(UrlInfo* info) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1112 break; | 1059 break; |
| 1113 info = &results_[work_queue_.Pop()]; | 1060 info = &results_[work_queue_.Pop()]; |
| 1114 info->SetAssignedState(); | 1061 info->SetAssignedState(); |
| 1115 } | 1062 } |
| 1116 return true; | 1063 return true; |
| 1117 } | 1064 } |
| 1118 | 1065 |
| 1119 void Predictor::StartSomeQueuedResolutions() { | 1066 void Predictor::StartSomeQueuedResolutions() { |
| 1120 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1067 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1121 | 1068 |
| 1122 // If the queue is disabled, just make LookupRequests for all entries. | 1069 // If the queue is disabled, just make requests for all entries. |
| 1123 bool enable_queue = base::FeatureList::IsEnabled(kUsePredictorDNSQueue); | 1070 bool enable_queue = base::FeatureList::IsEnabled(kUsePredictorDNSQueue); |
| 1124 while (!work_queue_.IsEmpty() && | 1071 while ( |
| 1125 (!enable_queue || | 1072 !work_queue_.IsEmpty() && |
| 1126 pending_lookups_.size() < max_concurrent_dns_lookups_)) { | 1073 (!enable_queue || num_pending_lookups_ < max_concurrent_dns_lookups_)) { |
| 1127 const GURL url(work_queue_.Pop()); | 1074 const GURL url(work_queue_.Pop()); |
| 1128 UrlInfo* info = &results_[url]; | 1075 UrlInfo* info = &results_[url]; |
| 1129 DCHECK(info->HasUrl(url)); | 1076 DCHECK(info->HasUrl(url)); |
| 1130 info->SetAssignedState(); | 1077 info->SetAssignedState(); |
| 1131 | 1078 |
| 1132 // Only perform congestion control if the queue is enabled. | 1079 // Only perform congestion control if the queue is enabled. |
| 1133 if (enable_queue && CongestionControlPerformed(info)) { | 1080 if (enable_queue && CongestionControlPerformed(info)) { |
| 1134 DCHECK(work_queue_.IsEmpty()); | 1081 DCHECK(work_queue_.IsEmpty()); |
| 1135 return; | 1082 return; |
| 1136 } | 1083 } |
| 1137 | 1084 |
| 1138 LookupRequest* request = new LookupRequest(this, host_resolver_, url); | 1085 int status = |
| 1139 | 1086 content::PreresolveUrl(profile_io_data_->GetResourceContext(), url, |
| 1140 int status = request->Start(); | 1087 base::Bind(&Predictor::OnLookupFinished, |
| 1088 weak_factory_->GetWeakPtr(), url)); |
| 1141 if (status == net::ERR_IO_PENDING) { | 1089 if (status == net::ERR_IO_PENDING) { |
| 1142 // Will complete asynchronously. | 1090 // Will complete asynchronously. |
| 1143 pending_lookups_.insert(request); | 1091 num_pending_lookups_++; |
| 1144 peak_pending_lookups_ = std::max(peak_pending_lookups_, | 1092 peak_pending_lookups_ = |
| 1145 pending_lookups_.size()); | 1093 std::max(peak_pending_lookups_, num_pending_lookups_); |
| 1146 } else { | 1094 } else { |
| 1147 // Completed synchronously (was already cached by HostResolver), or else | 1095 // Completed synchronously (was already cached by HostResolver), or else |
| 1148 // there was (equivalently) some network error that prevents us from | 1096 // there was (equivalently) some network error that prevents us from |
| 1149 // finding the name. Status net::OK means it was "found." | 1097 // finding the name. Status net::OK means it was "found." |
| 1150 LookupFinished(request, url, status == net::OK); | 1098 LookupFinished(url, status == net::OK); |
| 1151 delete request; | |
| 1152 } | 1099 } |
| 1153 } | 1100 } |
| 1154 } | 1101 } |
| 1155 | 1102 |
| 1156 void Predictor::TrimReferrers() { | 1103 void Predictor::TrimReferrers() { |
| 1157 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1104 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1158 if (!urls_being_trimmed_.empty()) | 1105 if (!urls_being_trimmed_.empty()) |
| 1159 return; // There is incremental trimming in progress already. | 1106 return; // There is incremental trimming in progress already. |
| 1160 | 1107 |
| 1161 // Check to see if it is time to trim yet. | 1108 // Check to see if it is time to trim yet. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 } | 1220 } |
| 1274 | 1221 |
| 1275 Predictor::InitialObserver::~InitialObserver() { | 1222 Predictor::InitialObserver::~InitialObserver() { |
| 1276 } | 1223 } |
| 1277 | 1224 |
| 1278 void Predictor::InitialObserver::Append(const GURL& url, | 1225 void Predictor::InitialObserver::Append(const GURL& url, |
| 1279 Predictor* predictor) { | 1226 Predictor* predictor) { |
| 1280 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1227 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1281 | 1228 |
| 1282 // TODO(rlp): Do we really need the predictor check here? | 1229 // TODO(rlp): Do we really need the predictor check here? |
| 1283 if (NULL == predictor) | 1230 if (nullptr == predictor) |
| 1284 return; | 1231 return; |
| 1285 if (kStartupResolutionCount <= first_navigations_.size()) | 1232 if (kStartupResolutionCount <= first_navigations_.size()) |
| 1286 return; | 1233 return; |
| 1287 | 1234 |
| 1288 DCHECK(url.SchemeIsHTTPOrHTTPS()); | 1235 DCHECK(url.SchemeIsHTTPOrHTTPS()); |
| 1289 DCHECK_EQ(url, Predictor::CanonicalizeUrl(url)); | 1236 DCHECK_EQ(url, Predictor::CanonicalizeUrl(url)); |
| 1290 if (first_navigations_.find(url) == first_navigations_.end()) | 1237 if (first_navigations_.find(url) == first_navigations_.end()) |
| 1291 first_navigations_[url] = base::TimeTicks::Now(); | 1238 first_navigations_[url] = base::TimeTicks::Now(); |
| 1292 } | 1239 } |
| 1293 | 1240 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 } | 1310 } |
| 1364 | 1311 |
| 1365 void SimplePredictor::ShutdownOnUIThread() { | 1312 void SimplePredictor::ShutdownOnUIThread() { |
| 1366 SetShutdown(true); | 1313 SetShutdown(true); |
| 1367 } | 1314 } |
| 1368 | 1315 |
| 1369 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } | 1316 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
| 1370 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } | 1317 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
| 1371 | 1318 |
| 1372 } // namespace chrome_browser_net | 1319 } // namespace chrome_browser_net |
| OLD | NEW |