summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/dns_master.h
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/net/dns_master.h
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_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.h201
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__