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

Unified Diff: chrome/browser/net/dns_master.h

Issue 15076: Clean up dns prefetch code, and also port it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: use scoper for init & free 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/net/dns_master.h
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h
index 72116cdac48b7de71dfa0ae269b677839f12d250..8018e26857dba21685ca9b063775493778e800f2 100644
--- a/chrome/browser/net/dns_master.h
+++ b/chrome/browser/net/dns_master.h
@@ -3,59 +3,45 @@
// 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_
#include <map>
#include <queue>
+#include <set>
#include <string>
-#include "base/condition_variable.h"
-#include "base/scoped_ptr.h"
-#include "base/values.h"
+#include "base/lock.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);
+ // Too many concurrent lookups negate benefits of prefetching
+ // by trashing the OS cache.
+ static const size_t kMaxConcurrentLookups;
- ~DnsMaster() {
- if (!shutdown_)
- ShutdownSlaves(); // Ensure we did our cleanup.
- }
+ DnsMaster();
+ ~DnsMaster();
- // 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();
+ // Cancel pending requests and prevent new ones from being made.
+ void Shutdown();
// In some circumstances, for privacy reasons, all results should be
// discarded. This method gracefully handles that activity.
@@ -64,7 +50,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,
@@ -89,36 +75,6 @@ class DnsMaster {
// domains.
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.
- 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_;
- }
-
// Discard any referrer for which all the suggested host names are currently
// annotated with no user latency reduction. Also scale down (diminish) the
// total benefit of those that did help, so that their reported contribution
@@ -135,42 +91,58 @@ class DnsMaster {
// values into the current referrer list.
void DeserializeReferrers(const ListValue& referral_list);
- //----------------------------------------------------------------------------
- // 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);
-
- // Access methods for use by slave threads to callback with state updates.
- void SetFoundState(const std::string hostname);
- void SetNoSuchNameState(const std::string hostname);
+ 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.
- // Notification during ShutdownSlaves.
- void SetSlaveHasTerminated(int slave_index);
+ class LookupRequest;
- 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;
+ // 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();
+ }
+
+ // 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();
+ }
+
+ // Only for testing;
+ size_t peak_pending_lookups() const { return peak_pending_lookups_; }
+
+ // Access method for use by lookup request to pass resolution result.
+ void OnLookupFinished(LookupRequest* request,
+ const std::string& hostname, bool found);
+
// "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 variables listed below.
darin (slow to review) 2009/02/18 21:49:17 looks like a good comment to me.
Lock lock_;
// name_buffer_ holds a list of names we need to look up.
@@ -184,30 +156,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.
-
- // TODO(jrg): wait for CL 15076 from _ph to come in which resolves
- // this. In the short term this file is hacked to be happy when
- // included in render_process.h.
-#if defined(OS_WIN)
- // 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];
-#endif
-
- // shutdown_ is set to tell the slaves to terminate.
- bool shutdown_;
+ std::set<LookupRequest*> pending_lookups_;
- // The following is the maximum time the ShutdownSlaves method
- // will wait for all the slave processes to terminate.
- const base::TimeDelta kShutdownWaitTime_;
+ // For testing, to verify that we don't exceed the limit.
+ size_t peak_pending_lookups_;
+
+ // When true, we don't make new lookup requests.
+ bool shutdown_;
// A list of successful events resulting from pre-fetching.
DnsHostInfo::DnsInfoTable cache_hits_;
« 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