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

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

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