blob: d74773585d6c4ba94c06bda345fc48495fb50129 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// 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
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5// A DnsMaster object is instantiated once in the browser
6// process, and delivers DNS prefetch assignments (hostnames)
7// to any of several DnsSlave objects.
8// Most hostname lists are sent out by renderer processes, and
9// involve lists of hostnames that *might* be used in the near
10// future by the browsing user. The goal of this class is to
11// cause the underlying DNS structure to lookup a hostname before
12// it is really needed, and hence reduce latency in the standard
13// lookup paths. Since some DNS lookups may take a LONG time, we
14// use several DnsSlave threads to concurrently perform the
15// lookups.
16
[email protected]e8013b32008-10-27 18:55:5217#ifndef CHROME_BROWSER_NET_DNS_MASTER_H_
18#define CHROME_BROWSER_NET_DNS_MASTER_H_
initial.commit09911bf2008-07-26 23:55:2919
20#include <map>
21#include <queue>
22#include <string>
23
24#include "base/condition_variable.h"
25#include "base/scoped_ptr.h"
26#include "chrome/browser/net/dns_host_info.h"
27#include "chrome/common/net/dns.h"
28#include "googleurl/src/url_canon.h"
29
30namespace chrome_browser_net {
31
32class DnsSlave;
33
34typedef chrome_common_net::NameList NameList;
35typedef std::map<std::string, DnsHostInfo> Results;
36
37class DnsMaster {
38 public:
[email protected]65ae4bc2008-08-22 11:38:1739 // The number of slave processes that will do DNS prefetching
40 static const int kSlaveCountMax = 8;
initial.commit09911bf2008-07-26 23:55:2941
42 explicit DnsMaster(TimeDelta shutdown_wait_time);
43
44 ~DnsMaster() {
45 if (!shutdown_)
46 ShutdownSlaves(); // Ensure we did our cleanup.
47 }
48
49 // ShutdownSlaves() gets all spawned threads to terminate, closes
50 // their handles, and deletes their DnsSlave instances.
51 // Return value of true means all operations succeeded.
52 // Return value of false means that the threads wouldn't terminate,
53 // and that resources may leak. If this returns false, it is best
54 // to NOT delete this DnsMaster, as slave threads may still call into
55 // this object.
56 bool ShutdownSlaves();
57
58 // In some circumstances, for privacy reasons, all results should be
59 // discarded. This method gracefully handles that activity.
60 // Destroy all our internal state, which shows what names we've looked up, and
61 // how long each has taken, etc. etc. We also destroy records of suggesses
62 // (cache hits etc.).
63 void DiscardAllResults();
64
65 // Add hostname(s) to the queue for processing by slaves
66 void ResolveList(const NameList& hostnames);
67 void Resolve(const std::string& hostname);
68
69 // Get latency benefit of the prefetch that we are navigating to.
70 bool AcruePrefetchBenefits(DnsHostInfo* host_info);
71
72 void GetHtmlInfo(std::string* output);
73
74 // For testing only...
75 // Currently testing only provides a crude measure of success.
76 bool WasFound(const std::string& hostname) {
77 AutoLock auto_lock(lock_);
78 return (results_.find(hostname) != results_.end()) &&
79 results_[hostname].was_found();
80 }
81
82 // Accessor methods, used mostly for testing.
83 // Both functions return DnsHostInfo::kNullDuration if name was not yet
84 // processed enough.
85 TimeDelta GetResolutionDuration(const std::string hostname) {
86 AutoLock auto_lock(lock_);
87 if (results_.find(hostname) == results_.end())
88 return DnsHostInfo::kNullDuration;
89 return results_[hostname].resolve_duration();
90 }
91
92 TimeDelta GetQueueDuration(const std::string hostname) {
93 AutoLock auto_lock(lock_);
94 if (results_.find(hostname) == results_.end())
95 return DnsHostInfo::kNullDuration;
96 return results_[hostname].queue_duration();
97 }
98
99 int running_slave_count() {
100 AutoLock auto_lock(lock_);
101 return running_slave_count_;
102 }
103
104 //----------------------------------------------------------------------------
105 // Methods below this line should only be called by slave processes.
106
initial.commit09911bf2008-07-26 23:55:29107 // GetNextAssignment() gets the next hostname from queue for processing
108 // It is not meant to be public, and should only be used by the slave.
109 // GetNextAssignment() waits on a condition variable if there are no more
110 // names in queue.
111 // Return false if slave thread should terminate.
112 // Return true if slave thread should process the value.
113 bool GetNextAssignment(std::string* hostname);
114
115 // Access methods for use by slave threads to callback with state updates.
116 void SetFoundState(const std::string hostname);
117 void SetNoSuchNameState(const std::string hostname);
118
119 // Notification during ShutdownSlaves.
120 void SetSlaveHasTerminated(int slave_index);
121
122 private:
123 //----------------------------------------------------------------------------
124 // Internal helper functions
125
126 // "PreLocked" means that the caller has already Acquired lock_ in the
127 // following method names.
128 void PreLockedResolve(const std::string& hostname);
129 bool PreLockedCreateNewSlaveIfNeeded(); // Lazy slave processes creation.
130
initial.commit09911bf2008-07-26 23:55:29131 // Number of slave processes started early (to help with startup prefetch).
132 static const int kSlaveCountMin = 4;
133
134 Lock lock_;
135
136 // name_buffer_ holds a list of names we need to look up.
137 std::queue<std::string> name_buffer_;
138
139 // results_ contains information progress for existing/prior prefetches.
140 Results results_;
141
142 // Signaling slaves to process elements in the queue, or to terminate,
143 // is done using ConditionVariables.
144 ConditionVariable slaves_have_work_;
145
146 int slave_count_; // Count of slave processes started.
147 int running_slave_count_; // Count of slaves process still running.
148
149 // The following arrays are only initialized as
150 // slave_count_ grows (up to the indicated max).
151 DWORD thread_ids_[kSlaveCountMax];
152 HANDLE thread_handles_[kSlaveCountMax];
153 DnsSlave* slaves_[kSlaveCountMax];
154
155 // shutdown_ is set to tell the slaves to terminate.
156 bool shutdown_;
157
158 // The following is the maximum time the ShutdownSlaves method
159 // will wait for all the slave processes to terminate.
160 const TimeDelta kShutdownWaitTime_;
161
162 // A list of successful events resulting from pre-fetching.
163 DnsHostInfo::DnsInfoTable cache_hits_;
164 // A map of hosts that were evicted from our cache (after we prefetched them)
165 // and before the HTTP stack tried to look them up.
166 Results cache_eviction_map_;
167
[email protected]e8013b32008-10-27 18:55:52168 DISALLOW_COPY_AND_ASSIGN(DnsMaster);
initial.commit09911bf2008-07-26 23:55:29169};
170
171} // namespace chrome_browser_net
172
[email protected]e8013b32008-10-27 18:55:52173#endif // CHROME_BROWSER_NET_DNS_MASTER_H_
license.botbf09a502008-08-24 00:55:55174