diff options
Diffstat (limited to 'chrome/browser/net/dns_master.h')
-rw-r--r-- | chrome/browser/net/dns_master.h | 134 |
1 files changed, 48 insertions, 86 deletions
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h index 7620d7c..78f5540 100644 --- a/chrome/browser/net/dns_master.h +++ b/chrome/browser/net/dns_master.h @@ -3,16 +3,13 @@ // found in the LICENSE file. // A DnsMaster object is instantiated once in the browser -// process, and delivers DNS prefetch assignments (hostnames) -// to any of several DnsSlave objects. +// process, and manages asynchronous resolution of DNS hostnames. // Most hostname lists are sent out by renderer processes, and // involve lists of hostnames that *might* be used in the near // future by the browsing user. The goal of this class is to // cause the underlying DNS structure to lookup a hostname before // it is really needed, and hence reduce latency in the standard -// lookup paths. Since some DNS lookups may take a LONG time, we -// use several DnsSlave threads to concurrently perform the -// lookups. +// lookup paths. #ifndef CHROME_BROWSER_NET_DNS_MASTER_H_ #define CHROME_BROWSER_NET_DNS_MASTER_H_ @@ -21,40 +18,27 @@ #include <queue> #include <string> -#include "base/condition_variable.h" -#include "base/scoped_ptr.h" +#include "base/lock.h" +#include "base/revocable_store.h" #include "chrome/browser/net/dns_host_info.h" #include "chrome/browser/net/referrer.h" #include "chrome/common/net/dns.h" #include "googleurl/src/url_canon.h" +#include "testing/gtest/include/gtest/gtest_prod.h" namespace chrome_browser_net { -class DnsSlave; - typedef chrome_common_net::NameList NameList; typedef std::map<std::string, DnsHostInfo> Results; class DnsMaster { public: - // The number of slave processes that will do DNS prefetching - static const size_t kSlaveCountMax = 8; - - explicit DnsMaster(base::TimeDelta shutdown_wait_time); - - ~DnsMaster() { - if (!shutdown_) - ShutdownSlaves(); // Ensure we did our cleanup. - } + // Too many concurrent lookups negate benefits of prefetching + // by trashing the OS cache. + static const size_t kMaxConcurrentLookups; - // ShutdownSlaves() gets all spawned threads to terminate, closes - // their handles, and deletes their DnsSlave instances. - // Return value of true means all operations succeeded. - // Return value of false means that the threads wouldn't terminate, - // and that resources may leak. If this returns false, it is best - // to NOT delete this DnsMaster, as slave threads may still call into - // this object. - bool ShutdownSlaves(); + DnsMaster(); + ~DnsMaster(); // In some circumstances, for privacy reasons, all results should be // discarded. This method gracefully handles that activity. @@ -63,7 +47,7 @@ class DnsMaster { // (cache hits etc.). void DiscardAllResults(); - // Add hostname(s) to the queue for processing by slaves + // Add hostname(s) to the queue for processing. void ResolveList(const NameList& hostnames, DnsHostInfo::ResolutionMotivation motivation); void Resolve(const std::string& hostname, @@ -88,72 +72,62 @@ class DnsMaster { // domains. void GetHtmlInfo(std::string* output); - // For testing only... - // Currently testing only provides a crude measure of success. + private: + FRIEND_TEST(DnsMasterTest, BenefitLookupTest); + FRIEND_TEST(DnsMasterTest, ShutdownWhenResolutionIsPendingTest); + FRIEND_TEST(DnsMasterTest, SingleLookupTest); + FRIEND_TEST(DnsMasterTest, ConcurrentLookupTest); + FRIEND_TEST(DnsMasterTest, MassiveConcurrentLookupTest); + friend class WaitForResolutionHelper; // For testing. + + class LookupRequest; + + // A map that is keyed with the hostnames that we've learned were the cause + // of loading additional hostnames. The list of additional hostnames in held + // in a Referrer instance, which is found in this type. + typedef std::map<std::string, Referrer> Referrers; + + // Only for testing. Returns true if hostname has been successfully resolved + // (name found). bool WasFound(const std::string& hostname) { AutoLock auto_lock(lock_); return (results_.find(hostname) != results_.end()) && results_[hostname].was_found(); } - // Accessor methods, used mostly for testing. - // Both functions return DnsHostInfo::kNullDuration if name was not yet - // processed enough. - base::TimeDelta GetResolutionDuration(const std::string hostname) { + // Only for testing. Return how long was the resolution + // or DnsHostInfo::kNullDuration if it hasn't been resolved yet. + base::TimeDelta GetResolutionDuration(const std::string& hostname) { AutoLock auto_lock(lock_); if (results_.find(hostname) == results_.end()) return DnsHostInfo::kNullDuration; return results_[hostname].resolve_duration(); } - base::TimeDelta GetQueueDuration(const std::string hostname) { - AutoLock auto_lock(lock_); - if (results_.find(hostname) == results_.end()) - return DnsHostInfo::kNullDuration; - return results_[hostname].queue_duration(); - } - - size_t running_slave_count() { - AutoLock auto_lock(lock_); - return running_slave_count_; - } - - //---------------------------------------------------------------------------- - // Methods below this line should only be called by slave processes. - - // GetNextAssignment() gets the next hostname from queue for processing - // It is not meant to be public, and should only be used by the slave. - // GetNextAssignment() waits on a condition variable if there are no more - // names in queue. - // Return false if slave thread should terminate. - // Return true if slave thread should process the value. - bool GetNextAssignment(std::string* hostname); + // Only for testing; + size_t peak_pending_lookups() const { return peak_pending_lookups_; } - // Access methods for use by slave threads to callback with state updates. + // Access methods for use by lookup callbacks to pass resolution result. void SetFoundState(const std::string hostname); void SetNoSuchNameState(const std::string hostname); - // Notification during ShutdownSlaves. - void SetSlaveHasTerminated(int slave_index); - - private: - // A map that is keyed with the hostnames that we've learned were the cause - // of loading additional hostnames. The list of additional hostnames in held - // in a Referrer instance, which is found in this type. - typedef std::map<std::string, Referrer> Referrers; - // "PreLocked" means that the caller has already Acquired lock_ in the // following method names. // Queue hostname for resolution. If queueing was done, return the pointer // to the queued instance, otherwise return NULL. DnsHostInfo* PreLockedResolve(const std::string& hostname, DnsHostInfo::ResolutionMotivation motivation); - bool PreLockedCreateNewSlaveIfNeeded(); // Lazy slave processes creation. - // Number of slave processes started early (to help with startup prefetch). - static const size_t kSlaveCountMin = 4; + // Take lookup requests from name_buffer_ and tell HostResolver + // to look them up asynchronously, provided we don't exceed + // concurrent resolution limit. + void PreLockedScheduleLookups(); - // Synchronize access to results_, referrers_, and slave control data. + // Synchronize access to results_, referrers_, pending_lookups_. + // TODO(phajdan.jr): Re-evaluate usage of this lock. After restructuring + // the code to run only on the IO thread and using PostTask from other threads + // the lock should not be needed. If that's not possible, then at least its + // usage can be reduced. Lock lock_; // name_buffer_ holds a list of names we need to look up. @@ -167,25 +141,13 @@ class DnsMaster { // pre-resolve when there is a navigation to the orginial hostname. Referrers referrers_; - // Signaling slaves to process elements in the queue, or to terminate, - // is done using ConditionVariables. - ConditionVariable slaves_have_work_; - - size_t slave_count_; // Count of slave processes started. - size_t running_slave_count_; // Count of slaves process still running. - - // The following arrays are only initialized as - // slave_count_ grows (up to the indicated max). - DWORD thread_ids_[kSlaveCountMax]; - HANDLE thread_handles_[kSlaveCountMax]; - DnsSlave* slaves_[kSlaveCountMax]; + // Count of started, but not yet finished dns lookups + size_t pending_lookups_; - // shutdown_ is set to tell the slaves to terminate. - bool shutdown_; + // For testing, to verify that we don't exceed the limit; + size_t peak_pending_lookups_; - // The following is the maximum time the ShutdownSlaves method - // will wait for all the slave processes to terminate. - const base::TimeDelta kShutdownWaitTime_; + RevocableStore pending_callbacks_; // We'll cancel them on shutdown. // A list of successful events resulting from pre-fetching. DnsHostInfo::DnsInfoTable cache_hits_; |