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

Side by Side Diff: chrome/browser/net/dns_master.h

Issue 15076: Clean up dns prefetch code, and also port it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: use scoper for init & free Created 11 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/net/dns_host_info_unittest.cc ('k') | chrome/browser/net/dns_master.cc » ('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) 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 // A DnsMaster object is instantiated once in the browser 5 // A DnsMaster object is instantiated once in the browser
6 // process, and delivers DNS prefetch assignments (hostnames) 6 // process, and manages asynchronous resolution of DNS hostnames.
7 // to any of several DnsSlave objects.
8 // Most hostname lists are sent out by renderer processes, and 7 // Most hostname lists are sent out by renderer processes, and
9 // involve lists of hostnames that *might* be used in the near 8 // involve lists of hostnames that *might* be used in the near
10 // future by the browsing user. The goal of this class is to 9 // future by the browsing user. The goal of this class is to
11 // cause the underlying DNS structure to lookup a hostname before 10 // cause the underlying DNS structure to lookup a hostname before
12 // it is really needed, and hence reduce latency in the standard 11 // it is really needed, and hence reduce latency in the standard
13 // lookup paths. Since some DNS lookups may take a LONG time, we 12 // lookup paths.
14 // use several DnsSlave threads to concurrently perform the
15 // lookups.
16 13
17 #ifndef CHROME_BROWSER_NET_DNS_MASTER_H_ 14 #ifndef CHROME_BROWSER_NET_DNS_MASTER_H_
18 #define CHROME_BROWSER_NET_DNS_MASTER_H_ 15 #define CHROME_BROWSER_NET_DNS_MASTER_H_
19 16
20 #include <map> 17 #include <map>
21 #include <queue> 18 #include <queue>
19 #include <set>
22 #include <string> 20 #include <string>
23 21
24 #include "base/condition_variable.h" 22 #include "base/lock.h"
25 #include "base/scoped_ptr.h"
26 #include "base/values.h"
27 #include "chrome/browser/net/dns_host_info.h" 23 #include "chrome/browser/net/dns_host_info.h"
28 #include "chrome/browser/net/referrer.h" 24 #include "chrome/browser/net/referrer.h"
29 #include "chrome/common/net/dns.h" 25 #include "chrome/common/net/dns.h"
30 #include "googleurl/src/url_canon.h" 26 #include "googleurl/src/url_canon.h"
27 #include "testing/gtest/include/gtest/gtest_prod.h"
31 28
32 namespace chrome_browser_net { 29 namespace chrome_browser_net {
33 30
34 class DnsSlave;
35
36 typedef chrome_common_net::NameList NameList; 31 typedef chrome_common_net::NameList NameList;
37 typedef std::map<std::string, DnsHostInfo> Results; 32 typedef std::map<std::string, DnsHostInfo> Results;
38 33
39 class DnsMaster { 34 class DnsMaster {
40 public: 35 public:
41 // The number of slave processes that will do DNS prefetching 36 // Too many concurrent lookups negate benefits of prefetching
42 static const size_t kSlaveCountMax = 8; 37 // by trashing the OS cache.
38 static const size_t kMaxConcurrentLookups;
43 39
44 explicit DnsMaster(base::TimeDelta shutdown_wait_time); 40 DnsMaster();
41 ~DnsMaster();
45 42
46 ~DnsMaster() { 43 // Cancel pending requests and prevent new ones from being made.
47 if (!shutdown_) 44 void Shutdown();
48 ShutdownSlaves(); // Ensure we did our cleanup.
49 }
50
51 // ShutdownSlaves() gets all spawned threads to terminate, closes
52 // their handles, and deletes their DnsSlave instances.
53 // Return value of true means all operations succeeded.
54 // Return value of false means that the threads wouldn't terminate,
55 // and that resources may leak. If this returns false, it is best
56 // to NOT delete this DnsMaster, as slave threads may still call into
57 // this object.
58 bool ShutdownSlaves();
59 45
60 // In some circumstances, for privacy reasons, all results should be 46 // In some circumstances, for privacy reasons, all results should be
61 // discarded. This method gracefully handles that activity. 47 // discarded. This method gracefully handles that activity.
62 // Destroy all our internal state, which shows what names we've looked up, and 48 // Destroy all our internal state, which shows what names we've looked up, and
63 // how long each has taken, etc. etc. We also destroy records of suggesses 49 // how long each has taken, etc. etc. We also destroy records of suggesses
64 // (cache hits etc.). 50 // (cache hits etc.).
65 void DiscardAllResults(); 51 void DiscardAllResults();
66 52
67 // Add hostname(s) to the queue for processing by slaves 53 // Add hostname(s) to the queue for processing.
68 void ResolveList(const NameList& hostnames, 54 void ResolveList(const NameList& hostnames,
69 DnsHostInfo::ResolutionMotivation motivation); 55 DnsHostInfo::ResolutionMotivation motivation);
70 void Resolve(const std::string& hostname, 56 void Resolve(const std::string& hostname,
71 DnsHostInfo::ResolutionMotivation motivation); 57 DnsHostInfo::ResolutionMotivation motivation);
72 58
73 // Get latency benefit of the prefetch that we are navigating to. 59 // Get latency benefit of the prefetch that we are navigating to.
74 bool AccruePrefetchBenefits(const GURL& referrer, 60 bool AccruePrefetchBenefits(const GURL& referrer,
75 DnsHostInfo* navigation_info); 61 DnsHostInfo* navigation_info);
76 62
77 // Instigate prefetch of any domains we predict will be needed after this 63 // Instigate prefetch of any domains we predict will be needed after this
78 // navigation. 64 // navigation.
79 void NavigatingTo(const std::string& host_name); 65 void NavigatingTo(const std::string& host_name);
80 66
81 // Record details of a navigation so that we can preresolve the host name 67 // Record details of a navigation so that we can preresolve the host name
82 // ahead of time the next time the users navigates to the indicated host. 68 // ahead of time the next time the users navigates to the indicated host.
83 void NonlinkNavigation(const GURL& referrer, DnsHostInfo* navigation_info); 69 void NonlinkNavigation(const GURL& referrer, DnsHostInfo* navigation_info);
84 70
85 // Dump HTML table containing list of referrers for about:dns. 71 // Dump HTML table containing list of referrers for about:dns.
86 void GetHtmlReferrerLists(std::string* output); 72 void GetHtmlReferrerLists(std::string* output);
87 73
88 // Dump the list of currently know referrer domains and related prefetchable 74 // Dump the list of currently know referrer domains and related prefetchable
89 // domains. 75 // domains.
90 void GetHtmlInfo(std::string* output); 76 void GetHtmlInfo(std::string* output);
91 77
92 // For testing only...
93 // Currently testing only provides a crude measure of success.
94 bool WasFound(const std::string& hostname) {
95 AutoLock auto_lock(lock_);
96 return (results_.find(hostname) != results_.end()) &&
97 results_[hostname].was_found();
98 }
99
100 // Accessor methods, used mostly for testing.
101 // Both functions return DnsHostInfo::kNullDuration if name was not yet
102 // processed enough.
103 base::TimeDelta GetResolutionDuration(const std::string hostname) {
104 AutoLock auto_lock(lock_);
105 if (results_.find(hostname) == results_.end())
106 return DnsHostInfo::kNullDuration;
107 return results_[hostname].resolve_duration();
108 }
109
110 base::TimeDelta GetQueueDuration(const std::string hostname) {
111 AutoLock auto_lock(lock_);
112 if (results_.find(hostname) == results_.end())
113 return DnsHostInfo::kNullDuration;
114 return results_[hostname].queue_duration();
115 }
116
117 size_t running_slave_count() {
118 AutoLock auto_lock(lock_);
119 return running_slave_count_;
120 }
121
122 // Discard any referrer for which all the suggested host names are currently 78 // Discard any referrer for which all the suggested host names are currently
123 // annotated with no user latency reduction. Also scale down (diminish) the 79 // annotated with no user latency reduction. Also scale down (diminish) the
124 // total benefit of those that did help, so that their reported contribution 80 // total benefit of those that did help, so that their reported contribution
125 // wll go done by a factor of 2 each time we trim (moving the referrer closer 81 // wll go done by a factor of 2 each time we trim (moving the referrer closer
126 // to being discarded at a future Trim). 82 // to being discarded at a future Trim).
127 void TrimReferrers(); 83 void TrimReferrers();
128 84
129 // Construct a ListValue object that contains all the data in the referrers_ 85 // Construct a ListValue object that contains all the data in the referrers_
130 // so that it can be persisted in a pref. 86 // so that it can be persisted in a pref.
131 void SerializeReferrers(ListValue* referral_list); 87 void SerializeReferrers(ListValue* referral_list);
132 88
133 // Process a ListValue that contains all the data from a previous reference 89 // Process a ListValue that contains all the data from a previous reference
134 // list, as constructed by SerializeReferrers(), and add all the identified 90 // list, as constructed by SerializeReferrers(), and add all the identified
135 // values into the current referrer list. 91 // values into the current referrer list.
136 void DeserializeReferrers(const ListValue& referral_list); 92 void DeserializeReferrers(const ListValue& referral_list);
137 93
138 //---------------------------------------------------------------------------- 94 private:
139 // Methods below this line should only be called by slave processes. 95 FRIEND_TEST(DnsMasterTest, BenefitLookupTest);
96 FRIEND_TEST(DnsMasterTest, ShutdownWhenResolutionIsPendingTest);
97 FRIEND_TEST(DnsMasterTest, SingleLookupTest);
98 FRIEND_TEST(DnsMasterTest, ConcurrentLookupTest);
99 FRIEND_TEST(DnsMasterTest, MassiveConcurrentLookupTest);
100 friend class WaitForResolutionHelper; // For testing.
140 101
141 // GetNextAssignment() gets the next hostname from queue for processing 102 class LookupRequest;
142 // It is not meant to be public, and should only be used by the slave.
143 // GetNextAssignment() waits on a condition variable if there are no more
144 // names in queue.
145 // Return false if slave thread should terminate.
146 // Return true if slave thread should process the value.
147 bool GetNextAssignment(std::string* hostname);
148 103
149 // Access methods for use by slave threads to callback with state updates.
150 void SetFoundState(const std::string hostname);
151 void SetNoSuchNameState(const std::string hostname);
152
153 // Notification during ShutdownSlaves.
154 void SetSlaveHasTerminated(int slave_index);
155
156 private:
157 // A map that is keyed with the hostnames that we've learned were the cause 104 // A map that is keyed with the hostnames that we've learned were the cause
158 // of loading additional hostnames. The list of additional hostnames in held 105 // of loading additional hostnames. The list of additional hostnames in held
159 // in a Referrer instance, which is found in this type. 106 // in a Referrer instance, which is found in this type.
160 typedef std::map<std::string, Referrer> Referrers; 107 typedef std::map<std::string, Referrer> Referrers;
161 108
109 // Only for testing. Returns true if hostname has been successfully resolved
110 // (name found).
111 bool WasFound(const std::string& hostname) {
112 AutoLock auto_lock(lock_);
113 return (results_.find(hostname) != results_.end()) &&
114 results_[hostname].was_found();
115 }
116
117 // Only for testing. Return how long was the resolution
118 // or DnsHostInfo::kNullDuration if it hasn't been resolved yet.
119 base::TimeDelta GetResolutionDuration(const std::string& hostname) {
120 AutoLock auto_lock(lock_);
121 if (results_.find(hostname) == results_.end())
122 return DnsHostInfo::kNullDuration;
123 return results_[hostname].resolve_duration();
124 }
125
126 // Only for testing;
127 size_t peak_pending_lookups() const { return peak_pending_lookups_; }
128
129 // Access method for use by lookup request to pass resolution result.
130 void OnLookupFinished(LookupRequest* request,
131 const std::string& hostname, bool found);
132
162 // "PreLocked" means that the caller has already Acquired lock_ in the 133 // "PreLocked" means that the caller has already Acquired lock_ in the
163 // following method names. 134 // following method names.
164 // Queue hostname for resolution. If queueing was done, return the pointer 135 // Queue hostname for resolution. If queueing was done, return the pointer
165 // to the queued instance, otherwise return NULL. 136 // to the queued instance, otherwise return NULL.
166 DnsHostInfo* PreLockedResolve(const std::string& hostname, 137 DnsHostInfo* PreLockedResolve(const std::string& hostname,
167 DnsHostInfo::ResolutionMotivation motivation); 138 DnsHostInfo::ResolutionMotivation motivation);
168 bool PreLockedCreateNewSlaveIfNeeded(); // Lazy slave processes creation.
169 139
170 // Number of slave processes started early (to help with startup prefetch). 140 // Take lookup requests from name_buffer_ and tell HostResolver
171 static const size_t kSlaveCountMin = 4; 141 // to look them up asynchronously, provided we don't exceed
142 // concurrent resolution limit.
143 void PreLockedScheduleLookups();
172 144
173 // Synchronize access to results_, referrers_, and slave control data. 145 // Synchronize access to variables listed below.
darin (slow to review) 2009/02/18 21:49:17 looks like a good comment to me.
174 Lock lock_; 146 Lock lock_;
175 147
176 // name_buffer_ holds a list of names we need to look up. 148 // name_buffer_ holds a list of names we need to look up.
177 std::queue<std::string> name_buffer_; 149 std::queue<std::string> name_buffer_;
178 150
179 // results_ contains information for existing/prior prefetches. 151 // results_ contains information for existing/prior prefetches.
180 Results results_; 152 Results results_;
181 153
182 // For each hostname that we might navigate to (that we've "learned about") 154 // For each hostname that we might navigate to (that we've "learned about")
183 // we have a Referrer list. Each Referrer list has all hostnames we need to 155 // we have a Referrer list. Each Referrer list has all hostnames we need to
184 // pre-resolve when there is a navigation to the orginial hostname. 156 // pre-resolve when there is a navigation to the orginial hostname.
185 Referrers referrers_; 157 Referrers referrers_;
186 158
187 // Signaling slaves to process elements in the queue, or to terminate, 159 std::set<LookupRequest*> pending_lookups_;
188 // is done using ConditionVariables.
189 ConditionVariable slaves_have_work_;
190 160
191 size_t slave_count_; // Count of slave processes started. 161 // For testing, to verify that we don't exceed the limit.
192 size_t running_slave_count_; // Count of slaves process still running. 162 size_t peak_pending_lookups_;
193 163
194 // TODO(jrg): wait for CL 15076 from _ph to come in which resolves 164 // When true, we don't make new lookup requests.
195 // this. In the short term this file is hacked to be happy when
196 // included in render_process.h.
197 #if defined(OS_WIN)
198 // The following arrays are only initialized as
199 // slave_count_ grows (up to the indicated max).
200 DWORD thread_ids_[kSlaveCountMax];
201 HANDLE thread_handles_[kSlaveCountMax];
202 DnsSlave* slaves_[kSlaveCountMax];
203 #endif
204
205 // shutdown_ is set to tell the slaves to terminate.
206 bool shutdown_; 165 bool shutdown_;
207 166
208 // The following is the maximum time the ShutdownSlaves method
209 // will wait for all the slave processes to terminate.
210 const base::TimeDelta kShutdownWaitTime_;
211
212 // A list of successful events resulting from pre-fetching. 167 // A list of successful events resulting from pre-fetching.
213 DnsHostInfo::DnsInfoTable cache_hits_; 168 DnsHostInfo::DnsInfoTable cache_hits_;
214 // A map of hosts that were evicted from our cache (after we prefetched them) 169 // A map of hosts that were evicted from our cache (after we prefetched them)
215 // and before the HTTP stack tried to look them up. 170 // and before the HTTP stack tried to look them up.
216 Results cache_eviction_map_; 171 Results cache_eviction_map_;
217 172
218 DISALLOW_COPY_AND_ASSIGN(DnsMaster); 173 DISALLOW_COPY_AND_ASSIGN(DnsMaster);
219 }; 174 };
220 175
221 } // namespace chrome_browser_net 176 } // namespace chrome_browser_net
222 177
223 #endif // CHROME_BROWSER_NET_DNS_MASTER_H_ 178 #endif // CHROME_BROWSER_NET_DNS_MASTER_H_
224 179
OLDNEW
« no previous file with comments | « chrome/browser/net/dns_host_info_unittest.cc ('k') | chrome/browser/net/dns_master.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698