| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/dns_master.h" | 5 #include "chrome/browser/net/dns_master.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/histogram.h" | 12 #include "base/histogram.h" |
| 13 #include "base/message_loop.h" | |
| 14 #include "base/lock.h" | 13 #include "base/lock.h" |
| 15 #include "base/stats_counters.h" | 14 #include "base/stats_counters.h" |
| 16 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 17 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "chrome/browser/chrome_thread.h" |
| 18 #include "net/base/address_list.h" | 18 #include "net/base/address_list.h" |
| 19 #include "net/base/completion_callback.h" | 19 #include "net/base/completion_callback.h" |
| 20 #include "net/base/host_resolver.h" | 20 #include "net/base/host_resolver.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 | 22 |
| 23 using base::TimeDelta; | 23 using base::TimeDelta; |
| 24 | 24 |
| 25 namespace chrome_browser_net { | 25 namespace chrome_browser_net { |
| 26 | 26 |
| 27 class DnsMaster::LookupRequest { | 27 class DnsMaster::LookupRequest { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 DnsMaster* master_; // Master which started us. | 63 DnsMaster* master_; // Master which started us. |
| 64 | 64 |
| 65 const std::string hostname_; // Hostname to resolve. | 65 const std::string hostname_; // Hostname to resolve. |
| 66 net::SingleRequestHostResolver resolver_; | 66 net::SingleRequestHostResolver resolver_; |
| 67 net::AddressList addresses_; | 67 net::AddressList addresses_; |
| 68 | 68 |
| 69 DISALLOW_COPY_AND_ASSIGN(LookupRequest); | 69 DISALLOW_COPY_AND_ASSIGN(LookupRequest); |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 DnsMaster::DnsMaster(net::HostResolver* host_resolver, | 72 DnsMaster::DnsMaster(net::HostResolver* host_resolver, |
| 73 MessageLoop* host_resolver_loop, | |
| 74 TimeDelta max_queue_delay, | 73 TimeDelta max_queue_delay, |
| 75 size_t max_concurrent) | 74 size_t max_concurrent) |
| 76 : peak_pending_lookups_(0), | 75 : peak_pending_lookups_(0), |
| 77 shutdown_(false), | 76 shutdown_(false), |
| 78 max_concurrent_lookups_(max_concurrent), | 77 max_concurrent_lookups_(max_concurrent), |
| 79 max_queue_delay_(max_queue_delay), | 78 max_queue_delay_(max_queue_delay), |
| 80 host_resolver_(host_resolver), | 79 host_resolver_(host_resolver) { |
| 81 host_resolver_loop_(host_resolver_loop) { | |
| 82 } | 80 } |
| 83 | 81 |
| 84 DnsMaster::~DnsMaster() { | 82 DnsMaster::~DnsMaster() { |
| 85 DCHECK(shutdown_); | 83 DCHECK(shutdown_); |
| 86 } | 84 } |
| 87 | 85 |
| 88 void DnsMaster::Shutdown() { | 86 void DnsMaster::Shutdown() { |
| 89 AutoLock auto_lock(lock_); | 87 AutoLock auto_lock(lock_); |
| 90 | 88 |
| 91 DCHECK(!shutdown_); | 89 DCHECK(!shutdown_); |
| 92 shutdown_ = true; | 90 shutdown_ = true; |
| 93 | 91 |
| 94 std::set<LookupRequest*>::iterator it; | 92 std::set<LookupRequest*>::iterator it; |
| 95 for (it = pending_lookups_.begin(); it != pending_lookups_.end(); ++it) | 93 for (it = pending_lookups_.begin(); it != pending_lookups_.end(); ++it) |
| 96 delete *it; | 94 delete *it; |
| 97 } | 95 } |
| 98 | 96 |
| 99 // Overloaded Resolve() to take a vector of names. | 97 // Overloaded Resolve() to take a vector of names. |
| 100 void DnsMaster::ResolveList(const NameList& hostnames, | 98 void DnsMaster::ResolveList(const NameList& hostnames, |
| 101 DnsHostInfo::ResolutionMotivation motivation) { | 99 DnsHostInfo::ResolutionMotivation motivation) { |
| 102 AutoLock auto_lock(lock_); | 100 AutoLock auto_lock(lock_); |
| 103 | 101 |
| 104 // We need to run this on |host_resolver_loop_| since we may access | 102 // We need to run this on the IO thread since we may access |
| 105 // |host_resolver_| which is not thread safe. | 103 // |host_resolver_| which is not thread safe. |
| 106 if (MessageLoop::current() != host_resolver_loop_) { | 104 if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 107 host_resolver_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 105 ChromeThread::PostTask( |
| 108 &DnsMaster::ResolveList, hostnames, motivation)); | 106 ChromeThread::IO, FROM_HERE, |
| 107 NewRunnableMethod( |
| 108 this, &DnsMaster::ResolveList, hostnames, motivation)); |
| 109 return; | 109 return; |
| 110 } | 110 } |
| 111 | 111 |
| 112 NameList::const_iterator it; | 112 NameList::const_iterator it; |
| 113 for (it = hostnames.begin(); it < hostnames.end(); ++it) | 113 for (it = hostnames.begin(); it < hostnames.end(); ++it) |
| 114 PreLockedResolve(*it, motivation); | 114 PreLockedResolve(*it, motivation); |
| 115 } | 115 } |
| 116 | 116 |
| 117 // Basic Resolve() takes an invidual name, and adds it | 117 // Basic Resolve() takes an invidual name, and adds it |
| 118 // to the queue. | 118 // to the queue. |
| 119 void DnsMaster::Resolve(const std::string& hostname, | 119 void DnsMaster::Resolve(const std::string& hostname, |
| 120 DnsHostInfo::ResolutionMotivation motivation) { | 120 DnsHostInfo::ResolutionMotivation motivation) { |
| 121 if (0 == hostname.length()) | 121 if (0 == hostname.length()) |
| 122 return; | 122 return; |
| 123 AutoLock auto_lock(lock_); | 123 AutoLock auto_lock(lock_); |
| 124 | 124 |
| 125 // We need to run this on |host_resolver_loop_| since we may access | 125 // We need to run this on the IO thread since we may access |
| 126 // |host_resolver_| which is not thread safe. | 126 // |host_resolver_| which is not thread safe. |
| 127 if (MessageLoop::current() != host_resolver_loop_) { | 127 if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 128 host_resolver_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 128 ChromeThread::PostTask( |
| 129 &DnsMaster::Resolve, hostname, motivation)); | 129 ChromeThread::IO, FROM_HERE, |
| 130 NewRunnableMethod(this, &DnsMaster::Resolve, hostname, motivation)); |
| 130 return; | 131 return; |
| 131 } | 132 } |
| 132 | 133 |
| 133 PreLockedResolve(hostname, motivation); | 134 PreLockedResolve(hostname, motivation); |
| 134 } | 135 } |
| 135 | 136 |
| 136 bool DnsMaster::AccruePrefetchBenefits(const GURL& referrer, | 137 bool DnsMaster::AccruePrefetchBenefits(const GURL& referrer, |
| 137 DnsHostInfo* navigation_info) { | 138 DnsHostInfo* navigation_info) { |
| 138 std::string hostname = navigation_info->hostname(); | 139 std::string hostname = navigation_info->hostname(); |
| 139 | 140 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 std::string referring_host = referrer.host(); | 199 std::string referring_host = referrer.host(); |
| 199 if (referring_host.empty() || referring_host == navigation_info->hostname()) | 200 if (referring_host.empty() || referring_host == navigation_info->hostname()) |
| 200 return; | 201 return; |
| 201 | 202 |
| 202 referrers_[referring_host].SuggestHost(navigation_info->hostname()); | 203 referrers_[referring_host].SuggestHost(navigation_info->hostname()); |
| 203 } | 204 } |
| 204 | 205 |
| 205 void DnsMaster::NavigatingTo(const std::string& host_name) { | 206 void DnsMaster::NavigatingTo(const std::string& host_name) { |
| 206 AutoLock auto_lock(lock_); | 207 AutoLock auto_lock(lock_); |
| 207 | 208 |
| 208 // We need to run this on |host_resolver_loop_| since we may access | 209 // We need to run this on the IO thread since we may access |
| 209 // |host_resolver_| which is not thread safe. | 210 // |host_resolver_| which is not thread safe. |
| 210 if (MessageLoop::current() != host_resolver_loop_) { | 211 if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 211 host_resolver_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 212 ChromeThread::PostTask( |
| 212 &DnsMaster::NavigatingTo, host_name)); | 213 ChromeThread::IO, FROM_HERE, |
| 214 NewRunnableMethod(this, &DnsMaster::NavigatingTo, host_name)); |
| 213 return; | 215 return; |
| 214 } | 216 } |
| 215 | 217 |
| 216 Referrers::iterator it = referrers_.find(host_name); | 218 Referrers::iterator it = referrers_.find(host_name); |
| 217 if (referrers_.end() == it) | 219 if (referrers_.end() == it) |
| 218 return; | 220 return; |
| 219 Referrer* referrer = &(it->second); | 221 Referrer* referrer = &(it->second); |
| 220 for (Referrer::iterator future_host = referrer->begin(); | 222 for (Referrer::iterator future_host = referrer->begin(); |
| 221 future_host != referrer->end(); ++future_host) { | 223 future_host != referrer->end(); ++future_host) { |
| 222 DnsHostInfo* queued_info = PreLockedResolve( | 224 DnsHostInfo* queued_info = PreLockedResolve( |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 return NULL; | 409 return NULL; |
| 408 } | 410 } |
| 409 | 411 |
| 410 info->SetQueuedState(motivation); | 412 info->SetQueuedState(motivation); |
| 411 work_queue_.Push(hostname, motivation); | 413 work_queue_.Push(hostname, motivation); |
| 412 PreLockedScheduleLookups(); | 414 PreLockedScheduleLookups(); |
| 413 return info; | 415 return info; |
| 414 } | 416 } |
| 415 | 417 |
| 416 void DnsMaster::PreLockedScheduleLookups() { | 418 void DnsMaster::PreLockedScheduleLookups() { |
| 417 // We need to run this on |host_resolver_loop_| since we may access | 419 // We need to run this on the IO thread since we may access |host_resolver_| |
| 418 // |host_resolver_| which is not thread safe. | 420 // which is not thread safe. |
| 419 DCHECK_EQ(MessageLoop::current(), host_resolver_loop_); | 421 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 420 | 422 |
| 421 while (!work_queue_.IsEmpty() && | 423 while (!work_queue_.IsEmpty() && |
| 422 pending_lookups_.size() < max_concurrent_lookups_) { | 424 pending_lookups_.size() < max_concurrent_lookups_) { |
| 423 const std::string hostname(work_queue_.Pop()); | 425 const std::string hostname(work_queue_.Pop()); |
| 424 DnsHostInfo* info = &results_[hostname]; | 426 DnsHostInfo* info = &results_[hostname]; |
| 425 DCHECK(info->HasHostname(hostname)); | 427 DCHECK(info->HasHostname(hostname)); |
| 426 info->SetAssignedState(); | 428 info->SetAssignedState(); |
| 427 | 429 |
| 428 if (PreLockedCongestionControlPerformed(info)) { | 430 if (PreLockedCongestionControlPerformed(info)) { |
| 429 DCHECK(work_queue_.IsEmpty()); | 431 DCHECK(work_queue_.IsEmpty()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 459 if (work_queue_.IsEmpty()) | 461 if (work_queue_.IsEmpty()) |
| 460 break; | 462 break; |
| 461 info = &results_[work_queue_.Pop()]; | 463 info = &results_[work_queue_.Pop()]; |
| 462 info->SetAssignedState(); | 464 info->SetAssignedState(); |
| 463 } | 465 } |
| 464 return true; | 466 return true; |
| 465 } | 467 } |
| 466 | 468 |
| 467 void DnsMaster::OnLookupFinished(LookupRequest* request, | 469 void DnsMaster::OnLookupFinished(LookupRequest* request, |
| 468 const std::string& hostname, bool found) { | 470 const std::string& hostname, bool found) { |
| 469 DCHECK_EQ(MessageLoop::current(), host_resolver_loop_); | 471 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 470 | 472 |
| 471 AutoLock auto_lock(lock_); // For map access (changing info values). | 473 AutoLock auto_lock(lock_); // For map access (changing info values). |
| 472 PrelockedLookupFinished(request, hostname, found); | 474 PrelockedLookupFinished(request, hostname, found); |
| 473 pending_lookups_.erase(request); | 475 pending_lookups_.erase(request); |
| 474 delete request; | 476 delete request; |
| 475 | 477 |
| 476 PreLockedScheduleLookups(); | 478 PreLockedScheduleLookups(); |
| 477 } | 479 } |
| 478 | 480 |
| 479 void DnsMaster::PrelockedLookupFinished(LookupRequest* request, | 481 void DnsMaster::PrelockedLookupFinished(LookupRequest* request, |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 std::string hostname(rush_queue_.front()); | 614 std::string hostname(rush_queue_.front()); |
| 613 rush_queue_.pop(); | 615 rush_queue_.pop(); |
| 614 return hostname; | 616 return hostname; |
| 615 } | 617 } |
| 616 std::string hostname(background_queue_.front()); | 618 std::string hostname(background_queue_.front()); |
| 617 background_queue_.pop(); | 619 background_queue_.pop(); |
| 618 return hostname; | 620 return hostname; |
| 619 } | 621 } |
| 620 | 622 |
| 621 } // namespace chrome_browser_net | 623 } // namespace chrome_browser_net |
| OLD | NEW |