diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/net/dns_master.h | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net/dns_master.h')
-rw-r--r-- | chrome/browser/net/dns_master.h | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h new file mode 100644 index 0000000..45dd00e --- /dev/null +++ b/chrome/browser/net/dns_master.h @@ -0,0 +1,201 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A DnsMaster object is instantiated once in the browser +// process, and delivers DNS prefetch assignments (hostnames) +// to any of several DnsSlave objects. +// 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. + +#ifndef CHROME_BROWSER_NET_DNS_MASTER_H__ +#define CHROME_BROWSER_NET_DNS_MASTER_H__ + +#include <map> +#include <queue> +#include <string> + +#include "base/condition_variable.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/net/dns_host_info.h" +#include "chrome/common/net/dns.h" +#include "googleurl/src/url_canon.h" + +namespace chrome_browser_net { + +class DnsSlave; + +typedef chrome_common_net::NameList NameList; +typedef std::map<std::string, DnsHostInfo> Results; + +class DnsMaster { + public: + + explicit DnsMaster(TimeDelta shutdown_wait_time); + + ~DnsMaster() { + if (!shutdown_) + ShutdownSlaves(); // Ensure we did our cleanup. + } + + // 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(); + + // In some circumstances, for privacy reasons, all results should be + // discarded. This method gracefully handles that activity. + // Destroy all our internal state, which shows what names we've looked up, and + // how long each has taken, etc. etc. We also destroy records of suggesses + // (cache hits etc.). + void DiscardAllResults(); + + // Add hostname(s) to the queue for processing by slaves + void ResolveList(const NameList& hostnames); + void Resolve(const std::string& hostname); + + // Get latency benefit of the prefetch that we are navigating to. + bool AcruePrefetchBenefits(DnsHostInfo* host_info); + + void GetHtmlInfo(std::string* output); + + // For testing only... + // Currently testing only provides a crude measure of success. + 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. + TimeDelta GetResolutionDuration(const std::string hostname) { + AutoLock auto_lock(lock_); + if (results_.find(hostname) == results_.end()) + return DnsHostInfo::kNullDuration; + return results_[hostname].resolve_duration(); + } + + TimeDelta GetQueueDuration(const std::string hostname) { + AutoLock auto_lock(lock_); + if (results_.find(hostname) == results_.end()) + return DnsHostInfo::kNullDuration; + return results_[hostname].queue_duration(); + } + + int running_slave_count() { + AutoLock auto_lock(lock_); + return running_slave_count_; + } + + //---------------------------------------------------------------------------- + // Methods below this line should only be called by slave processes. + + // Thread names can only be set after the thread has been running a bit. + void SetSlaveName(int slave_index); + + // 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); + + // Access methods for use by slave threads to callback with state updates. + void SetFoundState(const std::string hostname); + void SetNoSuchNameState(const std::string hostname); + + // Notification during ShutdownSlaves. + void SetSlaveHasTerminated(int slave_index); + + private: + //---------------------------------------------------------------------------- + // Internal helper functions + + // "PreLocked" means that the caller has already Acquired lock_ in the + // following method names. + void PreLockedResolve(const std::string& hostname); + bool PreLockedCreateNewSlaveIfNeeded(); // Lazy slave processes creation. + + // The number of slave processes that will do DNS prefetching + static const int kSlaveCountMax = 8; + // Number of slave processes started early (to help with startup prefetch). + static const int kSlaveCountMin = 4; + + Lock lock_; + + // name_buffer_ holds a list of names we need to look up. + std::queue<std::string> name_buffer_; + + // results_ contains information progress for existing/prior prefetches. + Results results_; + + // Signaling slaves to process elements in the queue, or to terminate, + // is done using ConditionVariables. + ConditionVariable slaves_have_work_; + + int slave_count_; // Count of slave processes started. + int 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]; + + // shutdown_ is set to tell the slaves to terminate. + bool shutdown_; + + // The following is the maximum time the ShutdownSlaves method + // will wait for all the slave processes to terminate. + const TimeDelta kShutdownWaitTime_; + + // A list of successful events resulting from pre-fetching. + DnsHostInfo::DnsInfoTable cache_hits_; + // A map of hosts that were evicted from our cache (after we prefetched them) + // and before the HTTP stack tried to look them up. + Results cache_eviction_map_; + + DISALLOW_EVIL_CONSTRUCTORS(DnsMaster); +}; + +} // namespace chrome_browser_net + +#endif // CHROME_BROWSER_NET_DNS_MASTER_H__ |