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 |