summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.scons5
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/browser_main.cc5
-rw-r--r--chrome/browser/browser_prefs.cc6
-rw-r--r--chrome/browser/browser_process_impl.cc6
-rw-r--r--chrome/browser/chrome_plugin_host.cc1
-rw-r--r--chrome/browser/net/dns_global.cc15
-rw-r--r--chrome/browser/net/dns_global.h14
-rw-r--r--chrome/browser/net/dns_host_info.cc4
-rw-r--r--chrome/browser/net/dns_host_info.h11
-rw-r--r--chrome/browser/net/dns_host_info_unittest.cc6
-rw-r--r--chrome/browser/net/dns_master.cc318
-rw-r--r--chrome/browser/net/dns_master.h157
-rw-r--r--chrome/browser/net/dns_master_unittest.cc477
-rw-r--r--chrome/browser/net/dns_slave.cc96
-rw-r--r--chrome/browser/net/dns_slave.h72
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj6
-rw-r--r--chrome/common/temp_scaffolding_stubs.cc26
-rw-r--r--chrome/test/unit/unit_tests.scons2
19 files changed, 415 insertions, 820 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index bc5860a..c3074b9 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -421,8 +421,6 @@ input_files = ChromeFileList([
'net/dns_host_info.h',
'net/dns_master.cc',
'net/dns_master.h',
- 'net/dns_slave.cc',
- 'net/dns_slave.h',
'net/referrer.cc',
'net/referrer.h',
'net/resolve_proxy_msg_helper.cc',
@@ -716,9 +714,6 @@ if not env.Bit('windows'):
'login_prompt.cc',
'memory_details.cc',
'modal_html_dialog_delegate.cc',
- 'net/dns_global.cc',
- 'net/dns_master.cc',
- 'net/dns_slave.cc',
'google_update.cc',
'password_manager/encryptor.cc',
'plugin_installer.cc',
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 2015099..ff3a63e 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -1594,14 +1594,6 @@
>
</File>
<File
- RelativePath=".\net\dns_slave.cc"
- >
- </File>
- <File
- RelativePath=".\net\dns_slave.h"
- >
- </File>
- <File
RelativePath=".\net\referrer.cc"
>
</File>
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index caaa963..c68d4a6 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -30,6 +30,7 @@
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/chrome_constants.h"
@@ -108,7 +109,7 @@ void WillTerminate();
#if defined(OS_WIN) || defined(OS_LINUX)
// Perform any platform-specific work that needs to be done before the main
-// message loop is created and initialized.
+// message loop is created and initialized.
void WillInitializeMainMessageLoop(const CommandLine & command_line) {
}
@@ -442,12 +443,14 @@ int BrowserMain(const MainFunctionParams& parameters) {
#if defined(OS_WIN)
// Initialize Winsock.
net::EnsureWinsockInit();
+#endif // defined(OS_WIN)
// Initialize the DNS prefetch system
chrome_browser_net::DnsPrefetcherInit dns_prefetch_init(user_prefs);
chrome_browser_net::DnsPrefetchHostNamesAtStartup(user_prefs, local_state);
chrome_browser_net::RestoreSubresourceReferrers(local_state);
+#if defined(OS_WIN)
// Init common control sex.
INITCOMMONCONTROLSEX config;
config.dwSize = sizeof(config);
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc
index fb39796..74aea18 100644
--- a/chrome/browser/browser_prefs.cc
+++ b/chrome/browser/browser_prefs.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
@@ -17,7 +18,6 @@
#include "chrome/browser/tab_contents/web_contents.h"
#if defined(OS_WIN) // TODO(port): whittle this down as we port
-#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/external_protocol_handler.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
@@ -44,10 +44,10 @@ void RegisterAllPrefs(PrefService* user_prefs, PrefService* local_state) {
MetricsLog::RegisterPrefs(local_state);
MetricsService::RegisterPrefs(local_state);
browser_shutdown::RegisterPrefs(local_state);
+ chrome_browser_net::RegisterPrefs(local_state);
#if defined(OS_WIN) // TODO(port): whittle this down as we port
BookmarkManagerView::RegisterPrefs(local_state);
BrowserView::RegisterBrowserViewPrefs(local_state);
- chrome_browser_net::RegisterPrefs(local_state);
PageInfoWindow::RegisterPrefs(local_state);
TaskManager::RegisterPrefs(local_state);
ExternalProtocolHandler::RegisterPrefs(local_state);
@@ -57,10 +57,10 @@ void RegisterAllPrefs(PrefService* user_prefs, PrefService* local_state) {
SessionStartupPref::RegisterUserPrefs(user_prefs);
Browser::RegisterUserPrefs(user_prefs);
PasswordManager::RegisterUserPrefs(user_prefs);
+ chrome_browser_net::RegisterUserPrefs(user_prefs);
#if defined(OS_WIN) // TODO(port): whittle this down as we port
BookmarkBarView::RegisterUserPrefs(user_prefs);
BookmarkTableView::RegisterUserPrefs(user_prefs);
- chrome_browser_net::RegisterUserPrefs(user_prefs);
DownloadManager::RegisterUserPrefs(user_prefs);
SSLManager::RegisterUserPrefs(user_prefs);
#endif
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index eb545e5..21bd96b 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/google_url_tracker.h"
#include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
@@ -174,6 +175,11 @@ BrowserProcessImpl::~BrowserProcessImpl() {
resource_dispatcher_host()->Shutdown();
}
+ // Shutdown DNS prefetching now to ensure that network stack objects
+ // living on the IO thread get destroyed before the IO thread goes away.
+ io_thread_->message_loop()->PostTask(FROM_HERE,
+ NewRunnableFunction(chrome_browser_net::ShutdownDnsPrefetch));
+
// Need to stop io_thread_ before resource_dispatcher_host_, since
// io_thread_ may still deref ResourceDispatcherHost and handle resource
// request before going away.
diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc
index 963bca1..67fce29 100644
--- a/chrome/browser/chrome_plugin_host.cc
+++ b/chrome/browser/chrome_plugin_host.cc
@@ -20,7 +20,6 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/dom_ui/html_dialog_contents.h"
#include "chrome/browser/gears_integration.h"
-#include "chrome/browser/net/dns_master.h"
#include "chrome/browser/plugin_process_host.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/profile.h"
diff --git a/chrome/browser/net/dns_global.cc b/chrome/browser/net/dns_global.cc
index 4e1f1a2..9733e52 100644
--- a/chrome/browser/net/dns_global.cc
+++ b/chrome/browser/net/dns_global.cc
@@ -382,7 +382,7 @@ void InitDnsPrefetch(PrefService* user_prefs) {
const TimeDelta kAllowableShutdownTime(TimeDelta::FromSeconds(10));
DCHECK(NULL == dns_master);
if (!dns_master) {
- dns_master = new DnsMaster(kAllowableShutdownTime);
+ dns_master = new DnsMaster();
// We did the initialization, so we should prime the pump, and set up
// the DNS resolution system to run.
off_the_record_observer.Register();
@@ -401,14 +401,13 @@ void InitDnsPrefetch(PrefService* user_prefs) {
void ShutdownDnsPrefetch() {
DCHECK(NULL != dns_master);
- DnsMaster* master = dns_master;
+ dns_master->Shutdown();
+}
+
+void FreeDnsPrefetchResources() {
+ DCHECK(NULL != dns_master);
+ delete dns_master;
dns_master = NULL;
- if (master->ShutdownSlaves()) {
- delete master;
- } else {
- // Leak instance if shutdown problem.
- DCHECK(0);
- }
}
static void DiscardAllPrefetchState() {
diff --git a/chrome/browser/net/dns_global.h b/chrome/browser/net/dns_global.h
index 2ba0e70..80cf6ff 100644
--- a/chrome/browser/net/dns_global.h
+++ b/chrome/browser/net/dns_global.h
@@ -19,10 +19,17 @@ class PrefService;
namespace chrome_browser_net {
-// Functions to initialize our global state so that PrefetchDns() can be called.
+// Initialize dns prefetching subsystem. Must be called before any other
+// functions.
void InitDnsPrefetch(PrefService* user_prefs);
+
+// Cancel pending lookup requests and don't make new ones.
void ShutdownDnsPrefetch();
+// Free all resources allocated by InitDnsPrefetch. After that you must not call
+// any function from this file.
+void FreeDnsPrefetchResources();
+
//------------------------------------------------------------------------------
// Global APIs relating to Prefetching in browser
void EnableDnsPrefetch(bool enable);
@@ -53,7 +60,10 @@ class DnsPrefetcherInit {
explicit DnsPrefetcherInit(PrefService* user_prefs) {
InitDnsPrefetch(user_prefs);
}
- ~DnsPrefetcherInit() {ShutdownDnsPrefetch();}
+
+ ~DnsPrefetcherInit() {
+ FreeDnsPrefetchResources();
+ }
private:
DISALLOW_COPY_AND_ASSIGN(DnsPrefetcherInit);
diff --git a/chrome/browser/net/dns_host_info.cc b/chrome/browser/net/dns_host_info.cc
index 844e24c..744fee0 100644
--- a/chrome/browser/net/dns_host_info.cc
+++ b/chrome/browser/net/dns_host_info.cc
@@ -39,8 +39,8 @@ bool DnsHostInfo::NeedsDnsUpdate(const std::string& hostname) {
return true;
case QUEUED: // In queue.
- case ASSIGNED: // Slave is working on it.
- case ASSIGNED_BUT_MARKED: // Slave is working on it.
+ case ASSIGNED: // It's being resolved.
+ case ASSIGNED_BUT_MARKED: // It's being resolved.
return false; // We're already working on it
case NO_SUCH_NAME: // Lookup failed.
diff --git a/chrome/browser/net/dns_host_info.h b/chrome/browser/net/dns_host_info.h
index 50c44f3..b9ea157 100644
--- a/chrome/browser/net/dns_host_info.h
+++ b/chrome/browser/net/dns_host_info.h
@@ -4,9 +4,8 @@
// A DnsHostInfo object is used to store status of a Dns lookup of a specific
// hostname.
-// It includes progress, from placement in the DnsMaster's queue, to assignment
-// to a slave, to resolution by the (blocking) DNS service as either FOUND or
-// NO_SUCH_NAME.
+// It includes progress, from placement in the DnsMaster's queue, to resolution
+// by the DNS service as either FOUND or NO_SUCH_NAME.
#ifndef CHROME_BROWSER_NET_DNS_HOST_INFO_H_
#define CHROME_BROWSER_NET_DNS_HOST_INFO_H_
@@ -54,9 +53,9 @@ class DnsHostInfo {
enum DnsProcessingState {
// When processed by our prefetching system, the states are:
PENDING, // Constructor has completed.
- QUEUED, // In prefetch queue but not yet assigned to a slave.
- ASSIGNED, // Currently being processed by a slave.
- ASSIGNED_BUT_MARKED, // Needs to be deleted as soon as slave is done.
+ QUEUED, // In prefetch queue but not yet being resolved.
+ ASSIGNED, // Currently being processed.
+ ASSIGNED_BUT_MARKED, // Needs to be deleted as soon as it's resolved.
FOUND, // DNS prefetch search completed.
NO_SUCH_NAME, // DNS prefetch search completed.
// When processed by the network stack during navigation, the states are:
diff --git a/chrome/browser/net/dns_host_info_unittest.cc b/chrome/browser/net/dns_host_info_unittest.cc
index c279804..a079716 100644
--- a/chrome/browser/net/dns_host_info_unittest.cc
+++ b/chrome/browser/net/dns_host_info_unittest.cc
@@ -41,8 +41,7 @@ TEST(DnsHostInfoTest, StateChangeTest) {
EXPECT_FALSE(info.NeedsDnsUpdate(hostname1))
<< "update needed after being queued";
info.SetAssignedState();
- EXPECT_FALSE(info.NeedsDnsUpdate(hostname1))
- << "update needed while assigned to slave";
+ EXPECT_FALSE(info.NeedsDnsUpdate(hostname1));
info.SetFoundState();
EXPECT_FALSE(info.NeedsDnsUpdate(hostname1))
<< "default expiration time is TOOOOO short";
@@ -64,8 +63,7 @@ TEST(DnsHostInfoTest, StateChangeTest) {
// be found. We'll sleep for a while, and then come back with not-found.
info.SetQueuedState(DnsHostInfo::UNIT_TEST_MOTIVATED);
info.SetAssignedState();
- EXPECT_FALSE(info.NeedsDnsUpdate(hostname1))
- << "update needed while assigned to slave";
+ EXPECT_FALSE(info.NeedsDnsUpdate(hostname1));
// Greater than minimal expected network latency on DNS lookup.
PlatformThread::Sleep(25);
info.SetNoSuchNameState();
diff --git a/chrome/browser/net/dns_master.cc b/chrome/browser/net/dns_master.cc
index d58bb4b..f2a584e 100644
--- a/chrome/browser/net/dns_master.cc
+++ b/chrome/browser/net/dns_master.cc
@@ -2,61 +2,87 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See header file for description of class
-
#include "chrome/browser/net/dns_master.h"
+#include <algorithm>
#include <set>
+#include <sstream>
+#include "base/compiler_specific.h"
#include "base/histogram.h"
+#include "base/lock.h"
+#include "base/ref_counted.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
-#include "base/thread.h"
-#include "base/win_util.h"
-#include "chrome/browser/net/dns_slave.h"
-
-using base::TimeDelta;
+#include "base/time.h"
+#include "net/base/address_list.h"
+#include "net/base/completion_callback.h"
+#include "net/base/host_resolver.h"
+#include "net/base/net_errors.h"
namespace chrome_browser_net {
-DnsMaster::DnsMaster(TimeDelta shutdown_wait_time)
- : slaves_have_work_(&lock_),
- slave_count_(0),
- running_slave_count_(0),
- shutdown_(false),
- kShutdownWaitTime_(shutdown_wait_time) {
- for (size_t i = 0; i < kSlaveCountMax; i++) {
- thread_ids_[i] = 0;
- thread_handles_[i] = 0;
- slaves_[i] = NULL;
+// static
+const size_t DnsMaster::kMaxConcurrentLookups = 8;
+
+class DnsMaster::LookupRequest {
+ public:
+ LookupRequest(DnsMaster* master, const std::string& hostname)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(
+ net_callback_(this, &LookupRequest::OnLookupFinished)),
+ master_(master),
+ hostname_(hostname) {
}
+
+ bool Start() {
+ const int result = resolver_.Resolve(hostname_, 80, &addresses_,
+ &net_callback_);
+ return (result == net::ERR_IO_PENDING);
+ }
+
+ private:
+ void OnLookupFinished(int result) {
+ master_->OnLookupFinished(this, hostname_, result == net::OK);
+ }
+
+ // HostResolver will call us using this callback when resolution is complete.
+ net::CompletionCallbackImpl<LookupRequest> net_callback_;
+
+ DnsMaster* master_; // Master which started us.
+
+ const std::string hostname_; // Hostname to resolve.
+ net::HostResolver resolver_;
+ net::AddressList addresses_;
+
+ DISALLOW_COPY_AND_ASSIGN(LookupRequest);
+};
+
+DnsMaster::DnsMaster() : peak_pending_lookups_(0), shutdown_(false) {
+}
+
+DnsMaster::~DnsMaster() {
+ DCHECK(shutdown_);
+}
+
+void DnsMaster::Shutdown() {
+ AutoLock auto_lock(lock_);
+
+ DCHECK(!shutdown_);
+ shutdown_ = true;
+
+ std::set<LookupRequest*>::iterator it;
+ for (it = pending_lookups_.begin(); it != pending_lookups_.end(); ++it)
+ delete *it;
}
// Overloaded Resolve() to take a vector of names.
void DnsMaster::ResolveList(const NameList& hostnames,
DnsHostInfo::ResolutionMotivation motivation) {
- bool need_to_signal = false;
- {
- AutoLock auto_lock(lock_);
- if (shutdown_) return;
- if (slave_count_ < kSlaveCountMin) {
- for (int target_count = std::min(hostnames.size(), kSlaveCountMin);
- target_count > 0;
- target_count--)
- PreLockedCreateNewSlaveIfNeeded();
- } else {
- PreLockedCreateNewSlaveIfNeeded(); // Allocate one per list call.
- }
+ AutoLock auto_lock(lock_);
- for (NameList::const_iterator it = hostnames.begin();
- it < hostnames.end();
- it++) {
- if (PreLockedResolve(*it, motivation))
- need_to_signal = true;
- }
- }
- if (need_to_signal)
- slaves_have_work_.Signal();
+ NameList::const_iterator it;
+ for (it = hostnames.begin(); it < hostnames.end(); ++it)
+ PreLockedResolve(*it, motivation);
}
// Basic Resolve() takes an invidual name, and adds it
@@ -65,16 +91,8 @@ void DnsMaster::Resolve(const std::string& hostname,
DnsHostInfo::ResolutionMotivation motivation) {
if (0 == hostname.length())
return;
- bool need_to_signal = false;
- {
- AutoLock auto_lock(lock_);
- if (shutdown_) return;
- PreLockedCreateNewSlaveIfNeeded(); // Allocate one at a time.
- if (PreLockedResolve(hostname, motivation))
- need_to_signal = true;
- }
- if (need_to_signal)
- slaves_have_work_.Signal();
+ AutoLock auto_lock(lock_);
+ PreLockedResolve(hostname, motivation);
}
bool DnsMaster::AccruePrefetchBenefits(const GURL& referrer,
@@ -147,26 +165,19 @@ void DnsMaster::NonlinkNavigation(const GURL& referrer,
}
void DnsMaster::NavigatingTo(const std::string& host_name) {
- bool need_to_signal = false;
- {
- AutoLock auto_lock(lock_);
- Referrers::iterator it = referrers_.find(host_name);
- if (referrers_.end() == it)
- return;
- Referrer* referrer = &(it->second);
- for (Referrer::iterator future_host = referrer->begin();
- future_host != referrer->end(); ++future_host) {
- DnsHostInfo* queued_info = PreLockedResolve(
- future_host->first,
- DnsHostInfo::LEARNED_REFERAL_MOTIVATED);
- if (queued_info) {
- need_to_signal = true;
- queued_info->SetReferringHostname(host_name);
- }
- }
+ AutoLock auto_lock(lock_);
+ Referrers::iterator it = referrers_.find(host_name);
+ if (referrers_.end() == it)
+ return;
+ Referrer* referrer = &(it->second);
+ for (Referrer::iterator future_host = referrer->begin();
+ future_host != referrer->end(); ++future_host) {
+ DnsHostInfo* queued_info = PreLockedResolve(
+ future_host->first,
+ DnsHostInfo::LEARNED_REFERAL_MOTIVATED);
+ if (queued_info)
+ queued_info->SetReferringHostname(host_name);
}
- if (need_to_signal)
- slaves_have_work_.Signal();
}
// Provide sort order so all .com's are together, etc.
@@ -297,7 +308,7 @@ void DnsMaster::GetHtmlInfo(std::string* output) {
}
if (!it->second.was_found())
continue; // Still being processed.
- if (TimeDelta() != it->second.benefits_remaining()) {
+ if (base::TimeDelta() != it->second.benefits_remaining()) {
network_hits.push_back(it->second); // With no benefit yet.
continue;
}
@@ -332,9 +343,11 @@ DnsHostInfo* DnsMaster::PreLockedResolve(
const std::string& hostname,
DnsHostInfo::ResolutionMotivation motivation) {
// DCHECK(We have the lock);
- DCHECK(0 != slave_count_);
DCHECK(0 != hostname.length());
+ if (shutdown_)
+ return NULL;
+
DnsHostInfo* info = &results_[hostname];
info->SetHostname(hostname); // Initialize or DCHECK.
// TODO(jar): I need to discard names that have long since expired.
@@ -349,151 +362,52 @@ DnsHostInfo* DnsMaster::PreLockedResolve(
info->SetQueuedState(motivation);
name_buffer_.push(hostname);
+
+ PreLockedScheduleLookups();
+
return info;
}
-// GetNextAssignment() is executed on the thread associated with
-// with a prefetch slave instance.
-// Return value of false indicates slave thread termination is needed.
-// Return value of true means info argument was populated
-// with a pointer to the assigned DnsHostInfo instance.
-bool DnsMaster::GetNextAssignment(std::string* hostname) {
- bool ask_for_help = false;
- {
- AutoLock auto_lock(lock_); // For map and buffer access
- while (0 == name_buffer_.size() && !shutdown_) {
- // No work pending, so just wait.
- // wait on condition variable while releasing lock temporarilly.
- slaves_have_work_.Wait();
- }
- if (shutdown_)
- return false; // Tell slaves to terminate also.
- *hostname = name_buffer_.front();
+void DnsMaster::PreLockedScheduleLookups() {
+ while (!name_buffer_.empty() &&
+ pending_lookups_.size() < kMaxConcurrentLookups) {
+ const std::string hostname(name_buffer_.front());
name_buffer_.pop();
- DnsHostInfo* info = &results_[*hostname];
- DCHECK(info->HasHostname(*hostname));
+ DnsHostInfo* info = &results_[hostname];
+ DCHECK(info->HasHostname(hostname));
info->SetAssignedState();
- ask_for_help = name_buffer_.size() > 0;
- } // Release lock_
- if (ask_for_help)
- slaves_have_work_.Signal();
- return true;
-}
-
-void DnsMaster::SetFoundState(const std::string hostname) {
- AutoLock auto_lock(lock_); // For map access (changing info values).
- DnsHostInfo* info = &results_[hostname];
- DCHECK(info->HasHostname(hostname));
- if (info->is_marked_to_delete())
- results_.erase(hostname);
- else
- info->SetFoundState();
+ LookupRequest* request = new LookupRequest(this, hostname);
+ if (request->Start()) {
+ pending_lookups_.insert(request);
+ peak_pending_lookups_ = std::max(peak_pending_lookups_,
+ pending_lookups_.size());
+ } else {
+ NOTREACHED();
+ delete request;
+ }
+ }
}
-void DnsMaster::SetNoSuchNameState(const std::string hostname) {
+void DnsMaster::OnLookupFinished(LookupRequest* request,
+ const std::string& hostname, bool found) {
AutoLock auto_lock(lock_); // For map access (changing info values).
DnsHostInfo* info = &results_[hostname];
DCHECK(info->HasHostname(hostname));
if (info->is_marked_to_delete())
results_.erase(hostname);
- else
- info->SetNoSuchNameState();
-}
-
-bool DnsMaster::PreLockedCreateNewSlaveIfNeeded() {
- // Don't create more than max.
- if (kSlaveCountMax <= slave_count_ || shutdown_)
- return false;
-
- DnsSlave* slave_instance = new DnsSlave(this, slave_count_);
- DWORD thread_id;
- size_t stack_size = 0;
- unsigned int flags = CREATE_SUSPENDED;
- if (win_util::GetWinVersion() >= win_util::WINVERSION_XP) {
- // 128kb stack size.
- stack_size = 128*1024;
- flags |= STACK_SIZE_PARAM_IS_A_RESERVATION;
+ else {
+ if (found)
+ info->SetFoundState();
+ else
+ info->SetNoSuchNameState();
}
- HANDLE handle = CreateThread(NULL, // security
- stack_size,
- DnsSlave::ThreadStart,
- reinterpret_cast<void*>(slave_instance),
- flags,
- &thread_id);
- DCHECK(NULL != handle);
- if (NULL == handle)
- return false;
-
- // Carlos suggests it is not valuable to do a set priority.
- // BOOL WINAPI SetThreadPriority(handle,int nPriority);
- thread_ids_[slave_count_] = thread_id;
- thread_handles_[slave_count_] = handle;
- slaves_[slave_count_] = slave_instance;
- slave_count_++;
+ pending_lookups_.erase(request);
+ delete request;
- ResumeThread(handle); // WINAPI call.
- running_slave_count_++;
-
- return true;
-}
-
-void DnsMaster::SetSlaveHasTerminated(int slave_index) {
- DCHECK_EQ(GetCurrentThreadId(), thread_ids_[slave_index]);
- AutoLock auto_lock(lock_);
- running_slave_count_--;
- DCHECK(thread_ids_[slave_index]);
- thread_ids_[slave_index] = 0;
-}
-
-bool DnsMaster::ShutdownSlaves() {
- int running_slave_count;
- {
- AutoLock auto_lock(lock_);
- shutdown_ = true; // Block additional resolution requests.
- // Empty the queue gracefully
- while (name_buffer_.size() > 0) {
- std::string hostname = name_buffer_.front();
- name_buffer_.pop();
- DnsHostInfo* info = &results_[hostname];
- DCHECK(info->HasHostname(hostname));
- // We should be in Queued state, so simulate to end of life.
- info->SetAssignedState(); // Simulate slave assignment.
- info->SetNoSuchNameState(); // Simulate failed lookup.
- results_.erase(hostname);
- }
- running_slave_count = running_slave_count_;
- // Release lock, so slaves can finish up.
- }
-
- if (running_slave_count) {
- slaves_have_work_.Broadcast(); // Slaves need to check for termination.
-
- DWORD result = WaitForMultipleObjects(
- slave_count_,
- thread_handles_,
- TRUE, // Wait for all
- static_cast<DWORD>(kShutdownWaitTime_.InMilliseconds()));
-
- DCHECK(result != WAIT_TIMEOUT) << "Some slaves didn't stop";
- if (WAIT_TIMEOUT == result)
- return false;
- }
- {
- AutoLock auto_lock(lock_);
- while (0 < slave_count_--) {
- if (0 == thread_ids_[slave_count_]) { // Thread terminated.
- int result = CloseHandle(thread_handles_[slave_count_]);
- CHECK(result);
- thread_handles_[slave_count_] = 0;
- delete slaves_[slave_count_];
- slaves_[slave_count_] = NULL;
- }
- }
- }
- return true;
+ PreLockedScheduleLookups();
}
void DnsMaster::DiscardAllResults() {
@@ -514,10 +428,11 @@ void DnsMaster::DiscardAllResults() {
info->SetAssignedState();
info->SetNoSuchNameState();
}
- // Now every result_ is either resolved, or is being worked on by a slave.
+ // Now every result_ is either resolved, or is being resolved
+ // (see LookupRequest).
// Step through result_, recording names of all hosts that can't be erased.
- // We can't erase anything being worked on by a slave.
+ // We can't erase anything being worked on.
Results assignees;
for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
std::string hostname = it->first;
@@ -528,9 +443,9 @@ void DnsMaster::DiscardAllResults() {
assignees[hostname] = *info;
}
}
- DCHECK(kSlaveCountMax >= assignees.size());
+ DCHECK(assignees.size() <= kMaxConcurrentLookups);
results_.clear();
- // Put back in the names being worked on by slaves.
+ // Put back in the names being worked on.
for (Results::iterator it = assignees.begin(); assignees.end() != it; ++it) {
DCHECK(it->second.is_marked_to_delete());
results_[it->first] = it->second;
@@ -584,4 +499,3 @@ void DnsMaster::DeserializeReferrers(const ListValue& referral_list) {
}
} // namespace chrome_browser_net
-
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h
index 72116cd..8018e26 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.
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_;
diff --git a/chrome/browser/net/dns_master_unittest.cc b/chrome/browser/net/dns_master_unittest.cc
index b9eb34f..aea38f5 100644
--- a/chrome/browser/net/dns_master_unittest.cc
+++ b/chrome/browser/net/dns_master_unittest.cc
@@ -2,104 +2,92 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Multi-threaded tests of DnsMaster and DnsPrefetch slave functionality.
-
#include <time.h>
-#include <ws2tcpip.h>
-#include <Wspiapi.h> // Needed for win2k compatibility
#include <algorithm>
-#include <map>
#include <sstream>
#include <string>
+#include "base/message_loop.h"
#include "base/platform_thread.h"
-#include "base/spin_wait.h"
+#include "base/scoped_ptr.h"
+#include "base/timer.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/dns_host_info.h"
-#include "chrome/browser/net/dns_slave.h"
+#include "chrome/common/net/dns.h"
+#include "net/base/address_list.h"
+#include "net/base/host_resolver.h"
+#include "net/base/host_resolver_unittest.h"
#include "net/base/winsock_init.h"
#include "testing/gtest/include/gtest/gtest.h"
-
using base::Time;
using base::TimeDelta;
-namespace {
+namespace chrome_browser_net {
-class DnsMasterTest : public testing::Test {
-};
+class WaitForResolutionHelper;
-typedef chrome_browser_net::DnsMaster DnsMaster;
-typedef chrome_browser_net::DnsPrefetcherInit DnsPrefetcherInit;
-typedef chrome_browser_net::DnsHostInfo DnsHostInfo;
-typedef chrome_browser_net::NameList NameList;
+typedef base::RepeatingTimer<WaitForResolutionHelper> HelperTimer;
+class WaitForResolutionHelper {
+ public:
+ WaitForResolutionHelper(DnsMaster* master, const NameList& hosts,
+ HelperTimer* timer)
+ : master_(master),
+ hosts_(hosts),
+ timer_(timer) {
+ }
-//------------------------------------------------------------------------------
-// Provide network function stubs to run tests offline (and avoid the variance
-// of real DNS lookups.
-//------------------------------------------------------------------------------
+ void Run() {
+ for (NameList::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i)
+ if (master_->GetResolutionDuration(*i) == DnsHostInfo::kNullDuration)
+ return; // We don't have resolution for that host.
-static void __stdcall fake_free_addr_info(struct addrinfo* ai) {
- // Kill off the dummy results.
- EXPECT_TRUE(NULL != ai);
- delete ai;
-}
+ // When all hostnames have been resolved, exit the loop.
+ timer_->Stop();
+ MessageLoop::current()->Quit();
+ delete timer_;
+ delete this;
+ }
-static int __stdcall fake_get_addr_info(const char* nodename,
- const char* servname,
- const struct addrinfo* hints,
- struct addrinfo** result) {
- static Lock lock;
- int duration;
- bool was_found;
- std::string hostname(nodename);
- // Dummy up *some* return results to pass along.
- *result = new addrinfo;
- EXPECT_TRUE(NULL != *result);
- {
- AutoLock autolock(lock);
-
- static bool initialized = false;
- typedef std::map<std::string, int> Latency;
- static Latency latency;
- static std::map<std::string, bool> found;
- if (!initialized) {
- initialized = true;
- // List all known hostnames
- latency["www.google.com"] = 50;
- latency["gmail.google.com.com"] = 70;
- latency["mail.google.com"] = 44;
- latency["gmail.com"] = 63;
-
- for (Latency::iterator it = latency.begin(); latency.end() != it; it++) {
- found[it->first] = true;
- }
- } // End static initialization
-
- was_found = found[hostname];
-
- if (latency.end() != latency.find(hostname)) {
- duration = latency[hostname];
- } else {
- duration = 500;
- }
- // Change latency to simulate cache warming (next latency will be short).
- latency[hostname] = 1;
- } // Release lock.
+ private:
+ DnsMaster* master_;
+ const NameList hosts_;
+ HelperTimer* timer_;
+};
- PlatformThread::Sleep(duration);
+class DnsMasterTest : public testing::Test {
+ public:
+ DnsMasterTest()
+ : mapper_(new net::RuleBasedHostMapper()),
+ scoped_mapper_(mapper_.get()) {
+ }
- return was_found ? 0 : WSAHOST_NOT_FOUND;
-}
+ protected:
+ virtual void SetUp() {
+#if defined(OS_WIN)
+ net::EnsureWinsockInit();
+#endif
+ mapper_->AddRuleWithLatency("www.google.com", "127.0.0.1", 50);
+ mapper_->AddRuleWithLatency("gmail.google.com.com", "127.0.0.1", 70);
+ mapper_->AddRuleWithLatency("mail.google.com", "127.0.0.1", 44);
+ mapper_->AddRuleWithLatency("gmail.com", "127.0.0.1", 63);
+ }
-static void SetupNetworkInfrastructure() {
- bool kUseFakeNetwork = true;
- if (kUseFakeNetwork)
- chrome_browser_net::SetAddrinfoCallbacks(fake_get_addr_info,
- fake_free_addr_info);
-}
+ void WaitForResolution(DnsMaster* master, const NameList& hosts) {
+ HelperTimer* timer = new HelperTimer();
+ timer->Start(TimeDelta::FromMilliseconds(100),
+ new WaitForResolutionHelper(master, hosts, timer),
+ &WaitForResolutionHelper::Run);
+ MessageLoop::current()->Run();
+ }
+
+ private:
+ MessageLoop loop;
+ scoped_refptr<net::RuleBasedHostMapper> mapper_;
+ net::ScopedHostMapper scoped_mapper_;
+};
//------------------------------------------------------------------------------
// Provide a function to create unique (nonexistant) domains at *every* call.
@@ -120,68 +108,63 @@ static std::string GetNonexistantDomain() {
// Use a blocking function to contrast results we get via async services.
//------------------------------------------------------------------------------
TimeDelta BlockingDnsLookup(const std::string& hostname) {
- char* port = "80"; // I may need to get the real port
- struct addrinfo* result = NULL;
Time start = Time::Now();
- // Use the same underlying methods as dns_prefetch_slave does
- chrome_browser_net::get_getaddrinfo()(hostname.c_str(), port,
- NULL, &result);
-
- TimeDelta duration = Time::Now() - start;
+ net::HostResolver resolver;
+ net::AddressList addresses;
+ resolver.Resolve(hostname, 80, &addresses, NULL);
- if (result) {
- chrome_browser_net::get_freeaddrinfo()(result);
- result = NULL;
- }
-
- return duration;
+ return Time::Now() - start;
}
//------------------------------------------------------------------------------
// First test to be sure the OS is caching lookups, which is the whole premise
// of DNS prefetching.
-TEST(DnsMasterTest, OsCachesLookupsTest) {
- SetupNetworkInfrastructure();
- net::EnsureWinsockInit();
-
- // To avoid flaky nature of a timed test, we'll run an outer loop until we get
- // 90% of the inner loop tests to pass.
- // Originally we just did one set of 5 tests and demand 100%, but that proved
- // flakey. With this set-looping approach, we always pass in one set (when it
- // used to pass). If we don't get that first set to pass, then we allow an
- // average of one failure per two major sets. If the test runs too long, then
- // there probably is a real problem, and the test harness will terminate us
- // with a failure.
- int pass_count(0);
- int fail_count(0);
- do {
- for (int i = 0; i < 5; i++) {
- std::string badname;
- badname = GetNonexistantDomain();
- TimeDelta duration = BlockingDnsLookup(badname);
- TimeDelta cached_duration = BlockingDnsLookup(badname);
- if (duration > cached_duration)
- pass_count++;
- else
- fail_count++;
- }
- } while (fail_count * 9 > pass_count);
+TEST_F(DnsMasterTest, OsCachesLookupsTest) {
+ const Time start = Time::Now();
+ int all_lookups = 0;
+ int lookups_with_improvement = 0;
+ // This test can be really flaky on Linux. It should run in much shorter time,
+ // but sometimes it won't and we don't like bogus failures.
+ while (Time::Now() - start < TimeDelta::FromMinutes(1)) {
+ std::string badname;
+ badname = GetNonexistantDomain();
+
+ TimeDelta duration = BlockingDnsLookup(badname);
+
+ // Produce more than one result and remove the largest one
+ // to reduce flakiness.
+ std::vector<TimeDelta> cached_results;
+ for (int j = 0; j < 3; j++)
+ cached_results.push_back(BlockingDnsLookup(badname));
+ std::sort(cached_results.begin(), cached_results.end());
+ cached_results.pop_back();
+
+ TimeDelta cached_sum = TimeDelta::FromSeconds(0);
+ for (std::vector<TimeDelta>::const_iterator j = cached_results.begin();
+ j != cached_results.end(); ++j)
+ cached_sum += *j;
+ TimeDelta cached_duration = cached_sum / cached_results.size();
+
+ all_lookups++;
+ if (cached_duration < duration)
+ lookups_with_improvement++;
+ if (all_lookups >= 10)
+ if (lookups_with_improvement * 100 > all_lookups * 75)
+ // Okay, we see the improvement for more than 75% of all lookups.
+ return;
+ }
+ FAIL() << "No substantial improvement in lookup time.";
}
-TEST(DnsMasterTest, StartupShutdownTest) {
- DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
-
- // With no threads, we should have no problem doing a shutdown.
- EXPECT_TRUE(testing_master.ShutdownSlaves());
+TEST_F(DnsMasterTest, StartupShutdownTest) {
+ DnsMaster testing_master;
+ testing_master.Shutdown();
}
-TEST(DnsMasterTest, BenefitLookupTest) {
- SetupNetworkInfrastructure();
- net::EnsureWinsockInit();
- DnsPrefetcherInit dns_init(NULL); // Creates global service .
- DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
+TEST_F(DnsMasterTest, BenefitLookupTest) {
+ DnsMaster testing_master;
std::string goog("www.google.com"),
goog2("gmail.google.com.com"),
@@ -211,23 +194,9 @@ TEST(DnsMasterTest, BenefitLookupTest) {
names.insert(names.end(), goog3);
names.insert(names.end(), goog4);
- // First only cause a minimal set of threads to start up.
- // Currently we actually start 4 threads when we get called with an array
testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
- // Wait for some resoultion for each google.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog2).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog3).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog4).InMilliseconds());
-
- EXPECT_EQ(std::min(names.size(),
- 4u /* chrome_browser_net::DnsMaster::kSlaveCountMin */ ),
- testing_master.running_slave_count());
+ WaitForResolution(&testing_master, names);
EXPECT_TRUE(testing_master.WasFound(goog));
EXPECT_TRUE(testing_master.WasFound(goog2));
@@ -250,67 +219,62 @@ TEST(DnsMasterTest, BenefitLookupTest) {
EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog3_info));
EXPECT_FALSE(testing_master.AccruePrefetchBenefits(GURL(), &goog4_info));
- // Ensure a clean shutdown.
- EXPECT_TRUE(testing_master.ShutdownSlaves());
+ testing_master.Shutdown();
}
-TEST(DnsMasterTest, DISABLED_SingleSlaveLookupTest) {
- SetupNetworkInfrastructure();
- net::EnsureWinsockInit();
- DnsPrefetcherInit dns_init(NULL); // Creates global service.
- DnsMaster testing_master(TimeDelta::FromMilliseconds(5000));
+TEST_F(DnsMasterTest, ShutdownWhenResolutionIsPendingTest) {
+ scoped_refptr<net::WaitingHostMapper> mapper = new net::WaitingHostMapper();
+ net::ScopedHostMapper scoped_mapper(mapper.get());
- std::string goog("www.google.com"),
- goog2("gmail.google.com.com"),
- goog3("mail.google.com"),
- goog4("gmail.com");
- std::string bad1(GetNonexistantDomain()),
- bad2(GetNonexistantDomain());
+ DnsMaster testing_master;
- // Warm up local OS cache.
- BlockingDnsLookup(goog);
+ std::string localhost("127.0.0.1");
+ NameList names;
+ names.insert(names.end(), localhost);
+
+ testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
+
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ new MessageLoop::QuitTask(), 500);
+ MessageLoop::current()->Run();
+
+ EXPECT_FALSE(testing_master.WasFound(localhost));
+
+ testing_master.Shutdown();
+
+ // Clean up after ourselves.
+ mapper->Signal();
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_F(DnsMasterTest, SingleLookupTest) {
+ DnsMaster testing_master;
+
+ std::string goog("www.google.com");
NameList names;
names.insert(names.end(), goog);
- names.insert(names.end(), bad1);
- names.insert(names.end(), bad2);
- // First only cause a single thread to start up
- testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
+ // Try to flood the master with many concurrent requests.
+ for (int i = 0; i < 10; i++)
+ testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
- // Wait for some resoultion for google.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog).InMilliseconds());
+ WaitForResolution(&testing_master, names);
EXPECT_TRUE(testing_master.WasFound(goog));
- EXPECT_FALSE(testing_master.WasFound(bad1));
- EXPECT_FALSE(testing_master.WasFound(bad2));
- // Verify the reason it is not found is that it is still being proceessed.
- // Negative time mean no resolution yet.
- EXPECT_GT(0, testing_master.GetResolutionDuration(bad2).InMilliseconds());
-
- // Spin long enough that we *do* find the resolution of bad2.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(bad2).InMilliseconds());
-
- // Verify both fictitious names are resolved by now.
- // Typical random name takes about 20-30 ms
- EXPECT_LT(0, testing_master.GetResolutionDuration(bad1).InMilliseconds());
- EXPECT_LT(0, testing_master.GetResolutionDuration(bad2).InMilliseconds());
- EXPECT_FALSE(testing_master.WasFound(bad1));
- EXPECT_FALSE(testing_master.WasFound(bad2));
- EXPECT_EQ(1U, testing_master.running_slave_count());
+ MessageLoop::current()->RunAllPending();
- // With just one thread (doing nothing now), ensure a clean shutdown.
- EXPECT_TRUE(testing_master.ShutdownSlaves());
+ EXPECT_GT(testing_master.peak_pending_lookups(), names.size() / 2);
+ EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master.peak_pending_lookups(),
+ DnsMaster::kMaxConcurrentLookups);
+
+ testing_master.Shutdown();
}
-TEST(DnsMasterTest, DISABLED_MultiThreadedLookupTest) {
- SetupNetworkInfrastructure();
- net::EnsureWinsockInit();
- DnsMaster testing_master(TimeDelta::FromSeconds(30));
- DnsPrefetcherInit dns_init(NULL);
+TEST_F(DnsMasterTest, ConcurrentLookupTest) {
+ DnsMaster testing_master;
std::string goog("www.google.com"),
goog2("gmail.google.com.com"),
@@ -334,12 +298,11 @@ TEST(DnsMasterTest, DISABLED_MultiThreadedLookupTest) {
BlockingDnsLookup(goog3);
BlockingDnsLookup(goog4);
- // Get all 8 threads running by calling many times before queue is handled.
- for (int i = 0; i < 10; i++) {
+ // Try to flood the master with many concurrent requests.
+ for (int i = 0; i < 10; i++)
testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
- }
- Sleep(10); // Allow time for async DNS to get answers.
+ WaitForResolution(&testing_master, names);
EXPECT_TRUE(testing_master.WasFound(goog));
EXPECT_TRUE(testing_master.WasFound(goog3));
@@ -348,99 +311,39 @@ TEST(DnsMasterTest, DISABLED_MultiThreadedLookupTest) {
EXPECT_FALSE(testing_master.WasFound(bad1));
EXPECT_FALSE(testing_master.WasFound(bad2));
- EXPECT_EQ(8U, testing_master.running_slave_count());
-
- EXPECT_TRUE(testing_master.ShutdownSlaves());
-}
-
-TEST(DnsMasterTest, DISABLED_MultiThreadedSpeedupTest) {
- SetupNetworkInfrastructure();
- net::EnsureWinsockInit();
- DnsMaster testing_master(TimeDelta::FromSeconds(30));
- DnsPrefetcherInit dns_init(NULL);
-
- std::string goog("www.google.com"),
- goog2("gmail.google.com.com"),
- goog3("mail.google.com"),
- goog4("gmail.com");
- std::string bad1(GetNonexistantDomain()),
- bad2(GetNonexistantDomain()),
- bad3(GetNonexistantDomain()),
- bad4(GetNonexistantDomain());
-
- NameList names;
- names.insert(names.end(), goog);
- names.insert(names.end(), bad1);
- names.insert(names.end(), bad2);
- names.insert(names.end(), goog3);
- names.insert(names.end(), goog2);
- names.insert(names.end(), bad3);
- names.insert(names.end(), bad4);
- names.insert(names.end(), goog4);
-
- // First cause a lookup using a single thread.
- testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
-
- // Wait for some resoultion for google.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog).InMilliseconds());
+ MessageLoop::current()->RunAllPending();
- EXPECT_TRUE(testing_master.WasFound(goog));
EXPECT_FALSE(testing_master.WasFound(bad1));
EXPECT_FALSE(testing_master.WasFound(bad2));
- // ...and due to delay in geting resolution of bad names, the single slave
- // thread won't have time to finish the list.
- EXPECT_FALSE(testing_master.WasFound(goog3));
- EXPECT_FALSE(testing_master.WasFound(goog2));
- EXPECT_FALSE(testing_master.WasFound(goog4));
-
- EXPECT_EQ(1U, testing_master.running_slave_count());
- // Get all 8 threads running by calling many times before queue is handled.
- names.clear();
- for (int i = 0; i < 10; i++)
- testing_master.Resolve(GetNonexistantDomain(),
- DnsHostInfo::PAGE_SCAN_MOTIVATED);
-
- // Wait long enough for all the goog's to be resolved.
- // They should all take about the same time, and run in parallel.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog2).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog3).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(goog4).InMilliseconds());
+ EXPECT_GT(testing_master.peak_pending_lookups(), names.size() / 2);
+ EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master.peak_pending_lookups(),
+ DnsMaster::kMaxConcurrentLookups);
- EXPECT_TRUE(testing_master.WasFound(goog3));
- EXPECT_TRUE(testing_master.WasFound(goog2));
- EXPECT_TRUE(testing_master.WasFound(goog4));
-
- EXPECT_FALSE(testing_master.WasFound(bad1));
- EXPECT_FALSE(testing_master.WasFound(bad2)); // Perhaps not even decided.
+ testing_master.Shutdown();
+}
- // Queue durations should be distinct from when 1 slave was working.
- EXPECT_GT(testing_master.GetQueueDuration(goog3).InMilliseconds(),
- testing_master.GetQueueDuration(goog).InMilliseconds());
- EXPECT_GT(testing_master.GetQueueDuration(goog4).InMilliseconds(),
- testing_master.GetQueueDuration(goog).InMilliseconds());
+TEST_F(DnsMasterTest, MassiveConcurrentLookupTest) {
+ DnsMaster testing_master;
- // Give bad names a chance to be determined as unresolved.
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(bad1).InMilliseconds());
- SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(0 <=
- testing_master.GetResolutionDuration(bad2).InMilliseconds());
+ NameList names;
+ for (int i = 0; i < 100; i++)
+ names.push_back(GetNonexistantDomain());
+ // Try to flood the master with many concurrent requests.
+ for (int i = 0; i < 10; i++)
+ testing_master.ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
- // Well known names should resolve faster than bad names.
- EXPECT_GE(testing_master.GetResolutionDuration(bad1).InMilliseconds(),
- testing_master.GetResolutionDuration(goog).InMilliseconds());
+ WaitForResolution(&testing_master, names);
- EXPECT_GE(testing_master.GetResolutionDuration(bad2).InMilliseconds(),
- testing_master.GetResolutionDuration(goog4).InMilliseconds());
+ MessageLoop::current()->RunAllPending();
- EXPECT_EQ(8U, testing_master.running_slave_count());
+ EXPECT_LE(testing_master.peak_pending_lookups(), names.size());
+ EXPECT_LE(testing_master.peak_pending_lookups(),
+ DnsMaster::kMaxConcurrentLookups);
- EXPECT_TRUE(testing_master.ShutdownSlaves());
+ testing_master.Shutdown();
}
//------------------------------------------------------------------------------
@@ -524,20 +427,22 @@ int GetLatencyFromSerialization(const std::string& motivation,
//------------------------------------------------------------------------------
// Make sure nil referral lists really have no entries, and no latency listed.
-TEST(DnsMasterTest, ReferrerSerializationNilTest) {
- DnsMaster master(TimeDelta::FromSeconds(30));
+TEST_F(DnsMasterTest, ReferrerSerializationNilTest) {
+ DnsMaster master;
ListValue referral_list;
master.SerializeReferrers(&referral_list);
- EXPECT_EQ(0, referral_list.GetSize());
+ EXPECT_EQ(0U, referral_list.GetSize());
EXPECT_EQ(kLatencyNotFound, GetLatencyFromSerialization("a.com", "b.com",
referral_list));
+
+ master.Shutdown();
}
// Make sure that when a serialization list includes a value, that it can be
// deserialized into the database, and can be extracted back out via
// serialization without being changed.
-TEST(DnsMasterTest, ReferrerSerializationSingleReferrerTest) {
- DnsMaster master(TimeDelta::FromSeconds(30));
+TEST_F(DnsMasterTest, ReferrerSerializationSingleReferrerTest) {
+ DnsMaster master;
std::string motivation_hostname = "www.google.com";
std::string subresource_hostname = "icons.google.com";
const int kLatency = 3;
@@ -550,15 +455,17 @@ TEST(DnsMasterTest, ReferrerSerializationSingleReferrerTest) {
ListValue recovered_referral_list;
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(1, recovered_referral_list.GetSize());
+ EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_EQ(kLatency, GetLatencyFromSerialization(motivation_hostname,
subresource_hostname,
recovered_referral_list));
+
+ master.Shutdown();
}
// Make sure the Trim() functionality works as expected.
-TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
- DnsMaster master(TimeDelta::FromSeconds(30));
+TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
+ DnsMaster master;
std::string motivation_hostname = "www.google.com";
std::string icon_subresource_hostname = "icons.google.com";
std::string img_subresource_hostname = "img.google.com";
@@ -573,7 +480,7 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
ListValue recovered_referral_list;
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(1, recovered_referral_list.GetSize());
+ EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_EQ(10, GetLatencyFromSerialization(motivation_hostname,
icon_subresource_hostname,
recovered_referral_list));
@@ -585,7 +492,7 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
// until they both are 0, an then a trim will delete the whole entry.
master.TrimReferrers();
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(1, recovered_referral_list.GetSize());
+ EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_EQ(5, GetLatencyFromSerialization(motivation_hostname,
icon_subresource_hostname,
recovered_referral_list));
@@ -595,7 +502,7 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
master.TrimReferrers();
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(1, recovered_referral_list.GetSize());
+ EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_EQ(2, GetLatencyFromSerialization(motivation_hostname,
icon_subresource_hostname,
recovered_referral_list));
@@ -605,7 +512,7 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
master.TrimReferrers();
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(1, recovered_referral_list.GetSize());
+ EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_EQ(1, GetLatencyFromSerialization(motivation_hostname,
icon_subresource_hostname,
recovered_referral_list));
@@ -615,7 +522,7 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
master.TrimReferrers();
master.SerializeReferrers(&recovered_referral_list);
- EXPECT_EQ(0, recovered_referral_list.GetSize());
+ EXPECT_EQ(0U, recovered_referral_list.GetSize());
EXPECT_EQ(kLatencyNotFound,
GetLatencyFromSerialization(motivation_hostname,
icon_subresource_hostname,
@@ -624,8 +531,8 @@ TEST(DnsMasterTest, ReferrerSerializationTrimTest) {
GetLatencyFromSerialization(motivation_hostname,
img_subresource_hostname,
recovered_referral_list));
-}
+ master.Shutdown();
+}
-} // namespace
-
+} // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_slave.cc b/chrome/browser/net/dns_slave.cc
deleted file mode 100644
index 2ffb78d..0000000
--- a/chrome/browser/net/dns_slave.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// See header file for description of class
-
-#include <ws2tcpip.h>
-#include <Wspiapi.h> // Needed for win2k compatibility
-
-#include "chrome/browser/net/dns_slave.h"
-
-#include "base/logging.h"
-#include "base/platform_thread.h"
-#include "base/string_util.h"
-#include "chrome/browser/net/dns_host_info.h"
-#include "chrome/browser/net/dns_master.h"
-
-
-namespace chrome_browser_net {
-
-//------------------------------------------------------------------------------
-// We supply a functions for stubbing network callbacks, so that offline testing
-// can be performed.
-//------------------------------------------------------------------------------
-static GetAddrInfoFunction get_addr = getaddrinfo;
-static FreeAddrInfoFunction free_addr = freeaddrinfo;
-void SetAddrinfoCallbacks(GetAddrInfoFunction getaddrinfo,
- FreeAddrInfoFunction freeaddrinfo) {
- get_addr = getaddrinfo;
- free_addr = freeaddrinfo;
-}
-
-GetAddrInfoFunction get_getaddrinfo() {return get_addr;}
-FreeAddrInfoFunction get_freeaddrinfo() {return free_addr;}
-
-
-//------------------------------------------------------------------------------
-// This is the entry method used by DnsMaster to start our thread.
-//------------------------------------------------------------------------------
-
-DWORD __stdcall DnsSlave::ThreadStart(void* pThis) {
- DnsSlave* slave_instance = reinterpret_cast<DnsSlave*>(pThis);
- return slave_instance->Run();
-}
-
-//------------------------------------------------------------------------------
-// The following are methods on the DnsPrefetch class.
-//------------------------------------------------------------------------------
-
-unsigned DnsSlave::Run() {
- DCHECK(slave_index_ >= 0 && slave_index_ < DnsMaster::kSlaveCountMax);
-
- std::string name = StringPrintf(
- "dns_prefetcher_%d_of_%d", slave_index_ + 1, DnsMaster::kSlaveCountMax);
- DLOG(INFO) << "Now Running " << name;
- PlatformThread::SetName(name.c_str());
-
- while (master_->GetNextAssignment(&hostname_)) {
- BlockingDnsLookup();
- }
- // GetNextAssignment() fails when we are told to terminate.
- master_->SetSlaveHasTerminated(slave_index_);
- return 0;
-}
-
-void DnsSlave::BlockingDnsLookup() {
- const char* port = "80"; // I may need to get the real port
- addrinfo* result = NULL;
-
- int error_code = get_addr(hostname_.c_str(), port, NULL, &result);
-
- // Note that since info has value semantics, I need to ask
- // master_ to set the new states atomically in its map.
- switch (error_code) {
- case 0:
- master_->SetFoundState(hostname_);
- break;
-
- default:
- DCHECK_EQ(0, error_code) << "surprising output" ;
- // fall through
-
- case WSAHOST_NOT_FOUND:
- master_->SetNoSuchNameState(hostname_);
- break;
- }
-
- // We don't save results, so lets free them...
- if (result) {
- free_addr(result);
- result = NULL;
- }
-}
-
-} // namespace chrome_browser_net
-
diff --git a/chrome/browser/net/dns_slave.h b/chrome/browser/net/dns_slave.h
deleted file mode 100644
index 6bbc17f..0000000
--- a/chrome/browser/net/dns_slave.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A DnsSlave object processes hostname lookups
-// via DNS on a single thread, waiting for that blocking
-// call to complete, and then getting its next hostname
-// from its associated DnsMaster object.
-// Since this class only is concerned with prefetching
-// to warm the underlying DNS cache, the actual IP
-// does not need to be recorded. It is necessary to record
-// when the lookup finished, so that the associated DnsMaster
-// won't (wastefully) ask for the same name in "too short a
-// period of time."
-// This class does no "de-duping," and merely slavishly services
-// items supplied by its DnsMaster.
-
-#ifndef CHROME_BROWSER_NET_DNS_SLAVE_H_
-#define CHROME_BROWSER_NET_DNS_SLAVE_H_
-
-#include <windows.h>
-#include <string>
-
-#include "base/basictypes.h"
-
-namespace chrome_browser_net {
-
-class DnsMaster;
-class DnsSlave;
-
-// Support testing infrastructure, and allow off-line testing.
-typedef void (__stdcall *FreeAddrInfoFunction)(struct addrinfo* ai);
-typedef int (__stdcall *GetAddrInfoFunction)(const char* nodename,
- const char* servname,
- const struct addrinfo* hints,
- struct addrinfo** result);
-void SetAddrinfoCallbacks(GetAddrInfoFunction getaddrinfo,
- FreeAddrInfoFunction freeaddrinfo);
-
-GetAddrInfoFunction get_getaddrinfo();
-FreeAddrInfoFunction get_freeaddrinfo();
-
-class DnsSlave {
- public:
- DnsSlave(DnsMaster* master, size_t slave_index)
- : master_(master),
- slave_index_(slave_index) {
- }
-
- ~DnsSlave() {
- master_ = NULL;
- }
-
- static DWORD WINAPI ThreadStart(void* pThis);
-
- unsigned Run();
-
- private:
- std::string hostname_; // Name being looked up.
-
- DnsMaster* master_; // Master that started us.
- size_t slave_index_; // Our index into DnsMaster's array.
-
- void BlockingDnsLookup();
-
- DISALLOW_COPY_AND_ASSIGN(DnsSlave);
-};
-
-} // namespace chrome_browser_net
-
-#endif // CHROME_BROWSER_NET_DNS_SLAVE_H_
-
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index c8957fb..e638c8b 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -77,8 +77,10 @@
/* Begin PBXBuildFile section */
0D71821EDDA2629232DE3AD9 /* safe_browsing_blocking_page.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFADB0E9D49DE009A6919 /* safe_browsing_blocking_page.cc */; };
0EE123B79B750A2FCEFB4569 /* history_backend_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9F00E9D48F7009A6919 /* history_backend_unittest.cc */; };
+ 1647A33CB5B4B14087BFF5C8 /* dns_global.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA680E9D4981009A6919 /* dns_global.cc */; };
1C284EB767D0E3D302AC675C /* tab_restore_service.cc in Sources */ = {isa = PBXBuildFile; fileRef = B020A11D500D7519E54F2957 /* tab_restore_service.cc */; };
2760C4346D6AB3AD94E9CF05 /* url_fixer_upper.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D16EF40F2145C600861FAC /* url_fixer_upper.cc */; };
+ 28283DBE4B6DB2B0F9893676 /* dns_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA6D0E9D4981009A6919 /* dns_master.cc */; };
2DF2A9EB8AF96926EE9B6B02 /* ipc_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBAE0E9D4C9F009A6919 /* ipc_logging.cc */; };
331218220F3BFF32006CB2B0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 331B93A90F3BF2B9008B1C46 /* QuartzCore.framework */; };
331218230F3BFF36006CB2B0 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 331B93AB0F3BF2DA008B1C46 /* Carbon.framework */; };
@@ -243,6 +245,7 @@
4DDC64580EAE394200FB5EBE /* libzlib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DDC64550EAE392400FB5EBE /* libzlib.a */; };
534E66C40F311BEC0006B2B2 /* temp_scaffolding_stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 534E66C30F311BEC0006B2B2 /* temp_scaffolding_stubs.cc */; };
544FBC49CB83E458B6B7069D /* test_web_contents.cc in Sources */ = {isa = PBXBuildFile; fileRef = 56E1D7DF17D327BFCB0B895D /* test_web_contents.cc */; };
+ 623E5BE905E098E8280304DA /* dns_master_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA6F0E9D4981009A6919 /* dns_master_unittest.cc */; };
6532B3A0E10294CDF999C20A /* child_process_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA9BC2620F44DCBE00588450 /* child_process_info.cc */; };
65930533A98EF22451EEA01D /* history_publisher_none.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7849CCC221723C1BC14D6384 /* history_publisher_none.cc */; };
6685F5375CC4ECE98C4C2213 /* browser_about_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8320E9D4839009A6919 /* browser_about_handler.cc */; };
@@ -5405,7 +5408,9 @@
844EA0880F3E0C4500B0EF26 /* debugger_io_socket.cc in Sources */,
844EA08D0F3E0C5000B0EF26 /* debugger_node.cc in Sources */,
844EA08E0F3E0C5900B0EF26 /* debugger_wrapper.cc in Sources */,
+ 1647A33CB5B4B14087BFF5C8 /* dns_global.cc in Sources */,
4D7BFA7C0E9D4994009A6919 /* dns_host_info.cc in Sources */,
+ 28283DBE4B6DB2B0F9893676 /* dns_master.cc in Sources */,
E4F324550EE5CFB1002533CE /* download_database.cc in Sources */,
E43A77170F16616E00ABD5D1 /* download_resource_handler.cc in Sources */,
E45075E30F150A6F003BE099 /* download_throttling_resource_handler.cc in Sources */,
@@ -5547,6 +5552,7 @@
E46C4EF30F27A9B000B393B8 /* command_updater_unittest.cc in Sources */,
331218330F3C0123006CB2B0 /* debug_message_handler.cc in Sources */,
4D7BFB510E9D4C3E009A6919 /* dns_host_info_unittest.cc in Sources */,
+ 623E5BE905E098E8280304DA /* dns_master_unittest.cc in Sources */,
E4F324950EE5D758002533CE /* extension_unittest.cc in Sources */,
A54612DC0EE9958600A8EE5D /* extensions_service_unittest.cc in Sources */,
331218300F3C010A006CB2B0 /* external_js_object.cc in Sources */,
diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc
index 78a223a..25520df 100644
--- a/chrome/common/temp_scaffolding_stubs.cc
+++ b/chrome/common/temp_scaffolding_stubs.cc
@@ -164,7 +164,7 @@ void OpenFirstRunDialog(Profile* profile) { NOTIMPLEMENTED(); }
GURL NewTabUIURL() {
NOTIMPLEMENTED();
- // TODO(port): returning a blank URL here confuses the page IDs so make sure
+ // TODO(port): returning a blank URL here confuses the page IDs so make sure
// we load something
return GURL("http://dev.chromium.org");
}
@@ -277,7 +277,7 @@ const std::wstring& TabContents::GetTitle() const {
NavigationEntry* entry = controller_->GetTransientEntry();
if (entry)
return entry->GetTitleForDisplay();
-
+
entry = controller_->GetLastCommittedEntry();
if (entry)
return entry->GetTitleForDisplay();
@@ -326,7 +326,7 @@ void TabContents::UpdateMaxPageID(int32 page_id) {
// testing.
if (GetSiteInstance())
GetSiteInstance()->UpdateMaxPageID(page_id);
-
+
if (AsWebContents())
AsWebContents()->process()->UpdateMaxPageID(page_id);
else
@@ -358,26 +358,6 @@ bool IsPluginProcess() {
//--------------------------------------------------------------------------
-namespace chrome_browser_net {
-
-void EnableDnsPrefetch(bool) { NOTIMPLEMENTED(); }
-
-void DnsPrefetchGetHtmlInfo(std::string* output) { NOTIMPLEMENTED(); }
-
-void DnsPrefetchList(const std::vector<std::string>& hostnames) {
- NOTIMPLEMENTED();
-}
-
-void SaveHostNamesForNextStartup(PrefService* local_state) { NOTIMPLEMENTED(); }
-
-void TrimSubresourceReferrers() { NOTIMPLEMENTED(); }
-
-void SaveSubresourceReferrers(PrefService* local_state) { NOTIMPLEMENTED(); }
-
-} // namespace chrome_browser_net
-
-//--------------------------------------------------------------------------
-
// This is from chrome_plugin_util.cc.
void CPB_Free(void* memory) { NOTIMPLEMENTED(); }
diff --git a/chrome/test/unit/unit_tests.scons b/chrome/test/unit/unit_tests.scons
index 24ddc5d..3779aabf 100644
--- a/chrome/test/unit/unit_tests.scons
+++ b/chrome/test/unit/unit_tests.scons
@@ -322,6 +322,7 @@ if env.Bit('mac'):
'$CHROME_DIR/browser/history/visit_tracker_unittest.cc',
'$CHROME_DIR/browser/metrics/metrics_response_unittest.cc',
'$CHROME_DIR/browser/net/dns_host_info_unittest.cc',
+ '$CHROME_DIR/browser/net/dns_master_unittest.cc',
'$CHROME_DIR/browser/net/url_fetcher_unittest.cc',
'$CHROME_DIR/browser/printing/page_range_unittest.cc',
'$CHROME_DIR/browser/printing/page_setup_unittest.cc',
@@ -401,7 +402,6 @@ if not env.Bit('windows'):
'$CHROME_DIR/browser/login_prompt_unittest.cc',
'$CHROME_DIR/browser/renderer_host/render_widget_host_unittests.cc',
'$CHROME_DIR/browser/navigation_controller_unittest.cc',
- '$CHROME_DIR/browser/net/dns_master_unittest.cc',
'$CHROME_DIR/browser/net/resolve_proxy_msg_helper_unittest.cc',
'$CHROME_DIR/browser/password_manager/encryptor_unittest.cc',
'$CHROME_DIR/browser/password_manager/password_form_manager_unittest.cc',