summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 17:46:27 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 17:46:27 +0000
commit0ac8368b361a5edbcfe4b985131a8eec13304f49 (patch)
treefbc7e4bdb86150f112730932c0d9d97fab16f4e0 /chrome
parent290da7ba0368e3cf1dbbe214a5be9f89666954d0 (diff)
downloadchromium_src-0ac8368b361a5edbcfe4b985131a8eec13304f49.zip
chromium_src-0ac8368b361a5edbcfe4b985131a8eec13304f49.tar.gz
chromium_src-0ac8368b361a5edbcfe4b985131a8eec13304f49.tar.bz2
Pull IOThread out of BrowserProcessImpl. Move the dns prefetching initialization into IOThread.
The global host resolver and dns master have changed to be member variables of IOThread. BUG=26156,26159 Review URL: http://codereview.chromium.org/553026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36866 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc1
-rw-r--r--chrome/browser/browser_process.h4
-rw-r--r--chrome/browser/browser_process_impl.cc104
-rw-r--r--chrome/browser/browser_process_impl.h5
-rw-r--r--chrome/browser/browser_process_sub_thread.cc40
-rw-r--r--chrome/browser/browser_process_sub_thread.h40
-rw-r--r--chrome/browser/gpu_process_host.cc1
-rw-r--r--chrome/browser/io_thread.cc183
-rw-r--r--chrome/browser/io_thread.h70
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc6
-rw-r--r--chrome/browser/net/chrome_url_request_context.h6
-rw-r--r--chrome/browser/net/dns_global.cc193
-rw-r--r--chrome/browser/net/dns_global.h29
-rw-r--r--chrome/browser/net/dns_master.h2
-rw-r--r--chrome/browser/net/ssl_config_service_manager_pref.cc1
-rw-r--r--chrome/browser/process_singleton_linux.cc1
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc1
-rwxr-xr-xchrome/chrome_browser.gypi4
-rw-r--r--chrome/test/in_process_browser_test.cc1
-rw-r--r--chrome/test/testing_browser_process.h4
-rw-r--r--chrome/test/ui/ui_test.cc1
21 files changed, 431 insertions, 266 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index df086ff..468e5e1 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -40,6 +40,7 @@
#include "chrome/browser/find_bar.h"
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/find_notification_details.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/login_prompt.h"
#include "chrome/browser/net/url_request_context_getter.h"
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index d1ba1a3..de74567 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -48,6 +48,8 @@ namespace printing {
class PrintJobManager;
}
+class IOThread;
+
// NOT THREAD SAFE, call only from the main thread.
// These functions shouldn't return NULL unless otherwise noted.
class BrowserProcess {
@@ -81,7 +83,7 @@ class BrowserProcess {
// ChromeThread::PostTask (or other variants) as they take care of checking
// that a thread is still alive, race conditions, lifetime differences etc.
// If you still must use this, need to check the return value for NULL.
- virtual base::Thread* io_thread() = 0;
+ virtual IOThread* io_thread() = 0;
// Returns the thread that we perform random file operations on. For code
// that wants to do I/O operations (not network requests or even file: URL
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 481d210..a63f6a4 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -12,6 +12,7 @@
#include "base/thread.h"
#include "base/waitable_event.h"
#include "chrome/browser/browser_main.h"
+#include "chrome/browser/browser_process_sub_thread.h"
#include "chrome/browser/browser_trial.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/debugger/debugger_wrapper.h"
@@ -21,6 +22,7 @@
#include "chrome/browser/google_url_tracker.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/intranet_redirect_detector.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
@@ -54,88 +56,6 @@
#include "chrome/common/render_messages.h"
#endif
-namespace {
-
-// ----------------------------------------------------------------------------
-// BrowserProcessSubThread
-//
-// This simple thread object is used for the specialized threads that the
-// BrowserProcess spins up.
-//
-// Applications must initialize the COM library before they can call
-// COM library functions other than CoGetMalloc and memory allocation
-// functions, so this class initializes COM for those users.
-class BrowserProcessSubThread : public ChromeThread {
- public:
- explicit BrowserProcessSubThread(ChromeThread::ID identifier)
- : ChromeThread(identifier) {
- }
-
- virtual ~BrowserProcessSubThread() {
- // We cannot rely on our base class to stop the thread since we want our
- // CleanUp function to run.
- Stop();
- }
-
- protected:
- virtual void Init() {
-#if defined(OS_WIN)
- // Initializes the COM library on the current thread.
- CoInitialize(NULL);
-#endif
-
- notification_service_ = new NotificationService;
- }
-
- virtual void CleanUp() {
- delete notification_service_;
- notification_service_ = NULL;
-
-#if defined(OS_WIN)
- // Closes the COM library on the current thread. CoInitialize must
- // be balanced by a corresponding call to CoUninitialize.
- CoUninitialize();
-#endif
- }
-
- private:
- // Each specialized thread has its own notification service.
- // Note: We don't use scoped_ptr because the destructor runs on the wrong
- // thread.
- NotificationService* notification_service_;
-};
-
-class IOThread : public BrowserProcessSubThread {
- public:
- IOThread() : BrowserProcessSubThread(ChromeThread::IO) {}
-
- virtual ~IOThread() {
- // We cannot rely on our base class to stop the thread since we want our
- // CleanUp function to run.
- Stop();
- }
-
- protected:
- virtual void CleanUp() {
- // URLFetcher and URLRequest instances must NOT outlive the IO thread.
- //
- // Strictly speaking, URLFetcher's CheckForLeaks() should be done on the
- // UI thread. However, since there _shouldn't_ be any instances left
- // at this point, it shouldn't be a race.
- //
- // We check URLFetcher first, since if it has leaked then an associated
- // URLRequest will also have leaked. However it is more useful to
- // crash showing the callstack of URLFetcher's allocation than its
- // URLRequest member.
- base::LeakTracker<URLFetcher>::CheckForLeaks();
- base::LeakTracker<URLRequest>::CheckForLeaks();
-
- BrowserProcessSubThread::CleanUp();
- }
-};
-
-} // namespace
-
BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line)
: created_resource_dispatcher_host_(false),
created_metrics_service_(false),
@@ -216,7 +136,7 @@ BrowserProcessImpl::~BrowserProcessImpl() {
// Need to stop io_thread_ before resource_dispatcher_host_, since
// io_thread_ may still deref ResourceDispatcherHost and handle resource
// request before going away.
- ResetIOThread();
+ io_thread_.reset();
// Stop the process launcher thread after the IO thread, in case the IO thread
// posted a task to terminate a process on the process launcher thread.
@@ -348,7 +268,7 @@ void BrowserProcessImpl::CreateIOThread() {
background_x11_thread_.swap(background_x11_thread);
#endif
- scoped_ptr<base::Thread> thread(new IOThread);
+ scoped_ptr<IOThread> thread(new IOThread);
base::Thread::Options options;
options.message_loop_type = MessageLoop::TYPE_IO;
if (!thread->StartWithOptions(options))
@@ -356,22 +276,6 @@ void BrowserProcessImpl::CreateIOThread() {
io_thread_.swap(thread);
}
-void BrowserProcessImpl::ResetIOThread() {
- if (io_thread_.get()) {
- io_thread_->message_loop()->PostTask(FROM_HERE,
- NewRunnableFunction(CleanupOnIOThread));
- }
- io_thread_.reset();
-}
-
-// static
-void BrowserProcessImpl::CleanupOnIOThread() {
- // Shutdown DNS prefetching now to ensure that network stack objects
- // living on the IO thread get destroyed before the IO thread goes away.
- chrome_browser_net::EnsureDnsPrefetchShutdown();
- // TODO(eroman): can this be merged into IOThread::CleanUp() ?
-}
-
void BrowserProcessImpl::CreateFileThread() {
DCHECK(!created_file_thread_ && file_thread_.get() == NULL);
created_file_thread_ = true;
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 2c815ee..e5c83e1 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -50,7 +50,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
return metrics_service_.get();
}
- virtual base::Thread* io_thread() {
+ virtual IOThread* io_thread() {
DCHECK(CalledOnValidThread());
if (!created_io_thread_)
CreateIOThread();
@@ -217,7 +217,6 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
void CreateMetricsService();
void CreateIOThread();
- void ResetIOThread();
static void CleanupOnIOThread();
void CreateFileThread();
@@ -246,7 +245,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
scoped_ptr<MetricsService> metrics_service_;
bool created_io_thread_;
- scoped_ptr<base::Thread> io_thread_;
+ scoped_ptr<IOThread> io_thread_;
#if defined(OS_LINUX)
// This shares a created flag with the IO thread.
scoped_ptr<base::Thread> background_x11_thread_;
diff --git a/chrome/browser/browser_process_sub_thread.cc b/chrome/browser/browser_process_sub_thread.cc
new file mode 100644
index 0000000..2e99d90
--- /dev/null
+++ b/chrome/browser/browser_process_sub_thread.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/browser/browser_process_sub_thread.h"
+#include "build/build_config.h"
+#include "chrome/common/notification_service.h"
+
+#if defined(OS_WIN)
+#include <Objbase.h>
+#endif
+
+BrowserProcessSubThread::BrowserProcessSubThread(ChromeThread::ID identifier)
+ : ChromeThread(identifier) {}
+
+BrowserProcessSubThread::~BrowserProcessSubThread() {
+ // We cannot rely on our base class to stop the thread since we want our
+ // CleanUp function to run.
+ Stop();
+}
+
+void BrowserProcessSubThread::Init() {
+#if defined(OS_WIN)
+ // Initializes the COM library on the current thread.
+ CoInitialize(NULL);
+#endif
+
+ notification_service_ = new NotificationService;
+}
+
+void BrowserProcessSubThread::CleanUp() {
+ delete notification_service_;
+ notification_service_ = NULL;
+
+#if defined(OS_WIN)
+ // Closes the COM library on the current thread. CoInitialize must
+ // be balanced by a corresponding call to CoUninitialize.
+ CoUninitialize();
+#endif
+}
diff --git a/chrome/browser/browser_process_sub_thread.h b/chrome/browser/browser_process_sub_thread.h
new file mode 100644
index 0000000..c16997b
--- /dev/null
+++ b/chrome/browser/browser_process_sub_thread.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_BROWSER_PROCESS_SUB_THREAD_H_
+#define CHROME_BROWSER_BROWSER_PROCESS_SUB_THREAD_H_
+
+#include "base/basictypes.h"
+#include "chrome/browser/chrome_thread.h"
+
+class NotificationService;
+
+// ----------------------------------------------------------------------------
+// BrowserProcessSubThread
+//
+// This simple thread object is used for the specialized threads that the
+// BrowserProcess spins up.
+//
+// Applications must initialize the COM library before they can call
+// COM library functions other than CoGetMalloc and memory allocation
+// functions, so this class initializes COM for those users.
+class BrowserProcessSubThread : public ChromeThread {
+ public:
+ explicit BrowserProcessSubThread(ChromeThread::ID identifier);
+ virtual ~BrowserProcessSubThread();
+
+ protected:
+ virtual void Init();
+ virtual void CleanUp();
+
+ private:
+ // Each specialized thread has its own notification service.
+ // Note: We don't use scoped_ptr because the destructor runs on the wrong
+ // thread.
+ NotificationService* notification_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserProcessSubThread);
+};
+
+#endif // CHROME_BROWSER_BROWSER_PROCESS_SUB_THREAD_H_
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 905f5c7..c56be79 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -9,6 +9,7 @@
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/child_process_launcher.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/common/child_process_host.h"
#include "chrome/common/child_process_info.h"
#include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
new file mode 100644
index 0000000..5625117
--- /dev/null
+++ b/chrome/browser/io_thread.cc
@@ -0,0 +1,183 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/browser/io_thread.h"
+#include "base/command_line.h"
+#include "base/leak_tracker.h"
+#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/net/dns_global.h"
+#include "chrome/browser/net/url_fetcher.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/base/fixed_host_resolver.h"
+#include "net/base/host_cache.h"
+#include "net/base/host_resolver.h"
+#include "net/url_request/url_request.h"
+
+namespace {
+
+net::HostResolver* CreateGlobalHostResolver() {
+ net::HostResolver* global_host_resolver = NULL;
+
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+
+ // The FixedHostResolver allows us to send all network requests through
+ // a designated test server.
+ if (command_line.HasSwitch(switches::kFixedHost)) {
+ std::string host =
+ command_line.GetSwitchValueASCII(switches::kFixedHost);
+ global_host_resolver = new net::FixedHostResolver(host);
+ } else {
+ global_host_resolver = net::CreateSystemHostResolver();
+
+ if (command_line.HasSwitch(switches::kDisableIPv6))
+ global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
+ }
+
+ return global_host_resolver;
+}
+
+} // namespace
+
+// The IOThread object must outlive any tasks posted to the IO thread before the
+// Quit task.
+template <>
+struct RunnableMethodTraits<IOThread> {
+ void RetainCallee(IOThread* /* io_thread */) {}
+ void ReleaseCallee(IOThread* /* io_thread */) {}
+};
+
+IOThread::IOThread()
+ : BrowserProcessSubThread(ChromeThread::IO),
+ host_resolver_(NULL),
+ prefetch_observer_(NULL),
+ dns_master_(NULL) {}
+
+IOThread::~IOThread() {
+ // We cannot rely on our base class to stop the thread since we want our
+ // CleanUp function to run.
+ Stop();
+}
+
+net::HostResolver* IOThread::host_resolver() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ return host_resolver_;
+}
+
+void IOThread::InitDnsMaster(
+ bool prefetching_enabled,
+ base::TimeDelta max_queue_delay,
+ size_t max_concurrent,
+ const chrome_common_net::NameList& hostnames_to_prefetch,
+ ListValue* referral_list) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ message_loop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &IOThread::InitDnsMasterOnIOThread,
+ prefetching_enabled, max_queue_delay, max_concurrent,
+ hostnames_to_prefetch, referral_list));
+}
+
+void IOThread::ChangedToOnTheRecord() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ message_loop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &IOThread::ChangedToOnTheRecordOnIOThread));
+}
+
+void IOThread::Init() {
+ BrowserProcessSubThread::Init();
+
+ DCHECK(!host_resolver_);
+ host_resolver_ = CreateGlobalHostResolver();
+ host_resolver_->AddRef();
+}
+
+void IOThread::CleanUp() {
+ // Not initialized in Init(). May not be initialized.
+ if (dns_master_) {
+ DCHECK(prefetch_observer_);
+
+ dns_master_->Shutdown();
+
+ // TODO(willchan): Stop reference counting DnsMaster. It's owned by
+ // IOThread now.
+ dns_master_->Release();
+ dns_master_ = NULL;
+ chrome_browser_net::FreeDnsPrefetchResources();
+ }
+
+ // Not initialized in Init(). May not be initialized.
+ if (prefetch_observer_) {
+ host_resolver_->RemoveObserver(prefetch_observer_);
+ delete prefetch_observer_;
+ prefetch_observer_ = NULL;
+ }
+
+ // TODO(eroman): temp hack for http://crbug.com/15513
+ host_resolver_->Shutdown();
+
+ // TODO(willchan): Stop reference counting HostResolver. It's owned by
+ // IOThread now.
+ host_resolver_->Release();
+ host_resolver_ = NULL;
+
+ // URLFetcher and URLRequest instances must NOT outlive the IO thread.
+ //
+ // Strictly speaking, URLFetcher's CheckForLeaks() should be done on the
+ // UI thread. However, since there _shouldn't_ be any instances left
+ // at this point, it shouldn't be a race.
+ //
+ // We check URLFetcher first, since if it has leaked then an associated
+ // URLRequest will also have leaked. However it is more useful to
+ // crash showing the callstack of URLFetcher's allocation than its
+ // URLRequest member.
+ base::LeakTracker<URLFetcher>::CheckForLeaks();
+ base::LeakTracker<URLRequest>::CheckForLeaks();
+
+ BrowserProcessSubThread::CleanUp();
+}
+
+void IOThread::InitDnsMasterOnIOThread(
+ bool prefetching_enabled,
+ base::TimeDelta max_queue_delay,
+ size_t max_concurrent,
+ chrome_common_net::NameList hostnames_to_prefetch,
+ ListValue* referral_list) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ CHECK(!dns_master_);
+
+ chrome_browser_net::EnableDnsPrefetch(prefetching_enabled);
+
+ dns_master_ = new chrome_browser_net::DnsMaster(
+ host_resolver_, max_queue_delay, max_concurrent);
+ dns_master_->AddRef();
+
+ DCHECK(!prefetch_observer_);
+ prefetch_observer_ = chrome_browser_net::CreatePrefetchObserver();
+ host_resolver_->AddObserver(prefetch_observer_);
+
+ FinalizeDnsPrefetchInitialization(
+ dns_master_, prefetch_observer_, hostnames_to_prefetch, referral_list);
+}
+
+void IOThread::ChangedToOnTheRecordOnIOThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+
+ if (dns_master_) {
+ // Destroy all evidence of our OTR session.
+ dns_master_->DnsMaster::DiscardAllResults();
+ }
+
+ // Clear the host cache to avoid showing entries from the OTR session
+ // in about:net-internals.
+ net::HostCache* host_cache = host_resolver_->GetHostCache();
+ if (host_cache)
+ host_cache->clear();
+}
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
new file mode 100644
index 0000000..f93f748
--- /dev/null
+++ b/chrome/browser/io_thread.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_IO_THREAD_H_
+#define CHROME_BROWSER_IO_THREAD_H_
+
+#include "base/basictypes.h"
+#include "base/task.h"
+#include "chrome/browser/browser_process_sub_thread.h"
+#include "chrome/common/net/dns.h"
+#include "net/base/host_resolver.h"
+
+class ListValue;
+
+namespace chrome_browser_net {
+class DnsMaster;
+} // namespace chrome_browser_net
+
+class IOThread : public BrowserProcessSubThread {
+ public:
+ IOThread();
+
+ virtual ~IOThread();
+
+ net::HostResolver* host_resolver();
+
+ // Initializes the DnsMaster. |prefetching_enabled| indicates whether or
+ // not dns prefetching should be enabled. This should be called by the UI
+ // thread. It will post a task to the IO thread to perform the actual
+ // initialization.
+ void InitDnsMaster(bool prefetching_enabled,
+ base::TimeDelta max_queue_delay,
+ size_t max_concurrent,
+ const chrome_common_net::NameList& hostnames_to_prefetch,
+ ListValue* referral_list);
+
+ // Handles changing to On The Record mode. Posts a task for this onto the
+ // IOThread's message loop.
+ void ChangedToOnTheRecord();
+
+ protected:
+ virtual void Init();
+ virtual void CleanUp();
+
+ private:
+ void InitDnsMasterOnIOThread(
+ bool prefetching_enabled,
+ base::TimeDelta max_queue_delay,
+ size_t max_concurrent,
+ chrome_common_net::NameList hostnames_to_prefetch,
+ ListValue* referral_list);
+
+ void ChangedToOnTheRecordOnIOThread();
+
+ // These member variables are basically global, but their lifetimes are tied
+ // to the IOThread. IOThread owns them all, despite not using scoped_ptr.
+ // This is because the destructor of IOThread runs on the wrong thread. All
+ // member variables should be deleted in CleanUp(). Most of these will be
+ // initialized in Init().
+
+ net::HostResolver* host_resolver_;
+
+ net::HostResolver::Observer* prefetch_observer_;
+ chrome_browser_net::DnsMaster* dns_master_;
+
+ DISALLOW_COPY_AND_ASSIGN(IOThread);
+};
+
+#endif // CHROME_BROWSER_IO_THREAD_H_
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index fda3916..7294359 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/privacy_blacklist/blacklist.h"
@@ -139,7 +140,7 @@ ChromeURLRequestContext* FactoryForOriginal::Create() {
ApplyProfileParametersToContext(context);
// Global host resolver for the context.
- context->set_host_resolver(chrome_browser_net::GetGlobalHostResolver());
+ context->set_host_resolver(io_thread()->host_resolver());
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
@@ -805,7 +806,8 @@ bool ChromeURLRequestContext::ShouldTrackRequest(const GURL& url) {
// ApplyProfileParametersToContext() which reverses this).
ChromeURLRequestContextFactory::ChromeURLRequestContextFactory(Profile* profile)
: is_media_(false),
- is_off_the_record_(profile->IsOffTheRecord()) {
+ is_off_the_record_(profile->IsOffTheRecord()),
+ io_thread_(g_browser_process->io_thread()) {
CheckCurrentlyOnMainThread();
PrefService* prefs = profile->GetPrefs();
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index b1384f6..55ec9cc 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -23,6 +23,7 @@ class ProxyConfig;
class ChromeURLRequestContext;
class ChromeURLRequestContextFactory;
+class IOThread;
// TODO(eroman): Cleanup the declaration order in this file -- it is all
// wonky to try and minimize awkward deltas.
@@ -335,6 +336,8 @@ class ChromeURLRequestContextFactory {
virtual ChromeURLRequestContext* Create() = 0;
protected:
+ IOThread* io_thread() { return io_thread_; }
+
// Assigns this factory's properties to |context|.
void ApplyProfileParametersToContext(ChromeURLRequestContext* context);
@@ -358,6 +361,9 @@ class ChromeURLRequestContextFactory {
FilePath profile_dir_path_;
+ private:
+ IOThread* const io_thread_;
+
DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory);
};
diff --git a/chrome/browser/net/dns_global.cc b/chrome/browser/net/dns_global.cc
index 082f423..6833dc0 100644
--- a/chrome/browser/net/dns_global.cc
+++ b/chrome/browser/net/dns_global.cc
@@ -7,7 +7,6 @@
#include <map>
#include <string>
-#include "base/command_line.h"
#include "base/singleton.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
@@ -15,7 +14,9 @@
#include "base/waitable_event.h"
#include "base/values.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/dns_host_info.h"
#include "chrome/browser/net/referrer.h"
#include "chrome/browser/profile.h"
@@ -24,8 +25,6 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
-#include "chrome/common/chrome_switches.h"
-#include "net/base/fixed_host_resolver.h"
#include "net/base/host_resolver.h"
#include "net/base/host_resolver_impl.h"
@@ -34,22 +33,21 @@ using base::TimeDelta;
namespace chrome_browser_net {
-static void ChangedToOnTheRecord();
static void DnsMotivatedPrefetch(const std::string& hostname,
DnsHostInfo::ResolutionMotivation motivation);
static void DnsPrefetchMotivatedList(
const NameList& hostnames,
DnsHostInfo::ResolutionMotivation motivation);
+static NameList GetDnsPrefetchHostNamesAtStartup(
+ PrefService* user_prefs, PrefService* local_state);
+
// static
const size_t DnsGlobalInit::kMaxPrefetchConcurrentLookups = 8;
// static
const int DnsGlobalInit::kMaxPrefetchQueueingDelayMs = 500;
-// Host resolver shared by DNS prefetcher, and the main URLRequestContext.
-static net::HostResolver* global_host_resolver = NULL;
-
//------------------------------------------------------------------------------
// This section contains all the globally accessable API entry points for the
// DNS Prefetching feature.
@@ -63,7 +61,7 @@ static bool on_the_record_switch = true;
// Enable/disable Dns prefetch activity (either via command line, or via pref).
void EnableDnsPrefetch(bool enable) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
dns_prefetch_enabled = enable;
}
@@ -72,12 +70,8 @@ void OnTheRecord(bool enable) {
if (on_the_record_switch == enable)
return;
on_the_record_switch = enable;
- if (on_the_record_switch) {
- ChromeThread::PostTask(
- ChromeThread::IO,
- FROM_HERE,
- NewRunnableFunction(ChangedToOnTheRecord));
- }
+ if (on_the_record_switch)
+ g_browser_process->io_thread()->ChangedToOnTheRecord();
}
void RegisterPrefs(PrefService* local_state) {
@@ -91,6 +85,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
// When enabled, we use the following instance to service all requests in the
// browser process.
+// TODO(willchan): Look at killing this.
static DnsMaster* dns_master = NULL;
// This API is only used in the browser process.
@@ -124,7 +119,7 @@ static void DnsPrefetchMotivatedList(
// This API is used by the autocomplete popup box (where URLs are typed).
void DnsPrefetchUrl(const GURL& url) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- if (!dns_prefetch_enabled || NULL == dns_master)
+ if (!dns_prefetch_enabled || NULL == dns_master)
return;
if (url.is_valid())
DnsMotivatedPrefetch(url.host(), DnsHostInfo::OMNIBOX_MOTIVATED);
@@ -204,6 +199,9 @@ class PrefetchObserver : public net::HostResolver::Observer {
static const size_t kStartupResolutionCount = 10;
};
+// TODO(willchan): Look at killing this global.
+static PrefetchObserver* g_prefetch_observer = NULL;
+
//------------------------------------------------------------------------------
// Member definitions for above Observer class.
@@ -388,7 +386,7 @@ void DnsPrefetchGetHtmlInfo(std::string* output) {
output->append("Incognito mode is active in a window.");
} else {
dns_master->GetHtmlInfo(output);
- Singleton<PrefetchObserver>::get()->DnsGetFirstResolutionsHtml(output);
+ g_prefetch_observer->DnsGetFirstResolutionsHtml(output);
dns_master->GetHtmlReferrerLists(output);
}
}
@@ -396,106 +394,56 @@ void DnsPrefetchGetHtmlInfo(std::string* output) {
}
//------------------------------------------------------------------------------
-// This section intializes and tears down global DNS prefetch services.
+// This section intializes global DNS prefetch services.
//------------------------------------------------------------------------------
-void InitDnsPrefetch(TimeDelta max_queue_delay, size_t max_concurrent,
- PrefService* user_prefs) {
+static void InitDnsPrefetch(TimeDelta max_queue_delay, size_t max_concurrent,
+ PrefService* user_prefs, PrefService* local_state) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- // Use a large shutdown time so that UI tests (that instigate lookups, and
- // then try to shutdown the browser) don't instigate the CHECK about
- // "some slaves have not finished"
- const TimeDelta kAllowableShutdownTime(TimeDelta::FromSeconds(10));
- DCHECK(NULL == dns_master);
- if (!dns_master) {
- // Have the DnsMaster issue resolve requests through a global HostResolver
- // that is shared by the main URLRequestContext, and lives on the IO thread.
- dns_master = new DnsMaster(GetGlobalHostResolver(),
- max_queue_delay, max_concurrent);
- dns_master->AddRef();
-
- if (user_prefs) {
- bool enabled = user_prefs->GetBoolean(prefs::kDnsPrefetchingEnabled);
- EnableDnsPrefetch(enabled);
- }
- DLOG(INFO) << "DNS Prefetch service started";
+ bool prefetching_enabled =
+ user_prefs->GetBoolean(prefs::kDnsPrefetchingEnabled);
- // Start observing real HTTP stack resolutions.
- // TODO(eroman): really this should be called from IO thread (since that is
- // where the host resolver lives). Since this occurs before requests have
- // started it is not a race yet.
- GetGlobalHostResolver()->AddObserver(Singleton<PrefetchObserver>::get());
- }
-}
-
-void EnsureDnsPrefetchShutdown() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ // Gather the list of hostnames to prefetch on startup.
+ NameList hostnames =
+ GetDnsPrefetchHostNamesAtStartup(user_prefs, local_state);
- if (NULL != dns_master) {
- dns_master->Shutdown();
+ ListValue* referral_list =
+ static_cast<ListValue*>(
+ local_state->GetMutableList(prefs::kDnsHostReferralList)->DeepCopy());
- // Stop observing DNS resolutions. Note that dns_master holds a reference
- // to the global host resolver, so is guaranteed to be live.
- global_host_resolver->RemoveObserver(Singleton<PrefetchObserver>::get());
- }
+ g_browser_process->io_thread()->InitDnsMaster(
+ prefetching_enabled, max_queue_delay, max_concurrent, hostnames,
+ referral_list);
+}
- if (global_host_resolver) {
- // TODO(eroman): temp hack for http://crbug.com/15513
- global_host_resolver->Shutdown();
+void FinalizeDnsPrefetchInitialization(
+ DnsMaster* global_dns_master,
+ net::HostResolver::Observer* global_prefetch_observer,
+ const NameList& hostnames_to_prefetch,
+ ListValue* referral_list) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ dns_master = global_dns_master;
+ g_prefetch_observer =
+ static_cast<PrefetchObserver*>(global_prefetch_observer);
- global_host_resolver->Release(); // Balances GetGlobalHostResolver().
+ DLOG(INFO) << "DNS Prefetch service started";
- // TODO(eroman): This is a hack so the in process browser tests work if
- // BrowserMain() is to be called again.
- global_host_resolver = NULL;
- }
+ // Prefetch these hostnames on startup.
+ DnsPrefetchMotivatedList(hostnames_to_prefetch,
+ DnsHostInfo::STARTUP_LIST_MOTIVATED);
+ dns_master->DeserializeReferrersThenDelete(referral_list);
}
void FreeDnsPrefetchResources() {
- DCHECK(NULL != dns_master);
- dns_master->Release();
dns_master = NULL;
-}
-
-static void ChangedToOnTheRecord() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
-
- if (dns_master) {
- // Destroy all evidence of our OTR session.
- dns_master->DnsMaster::DiscardAllResults();
- }
-
- // Clear the host cache to avoid showing entries from the OTR session
- // in about:net-internals.
- net::HostCache* host_cache = GetGlobalHostResolver()->GetHostCache();
- if (host_cache)
- host_cache->clear();
+ g_prefetch_observer = NULL;
}
//------------------------------------------------------------------------------
-net::HostResolver* GetGlobalHostResolver() {
- // Called from UI thread.
- if (!global_host_resolver) {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-
- // The FixedHostResolver allows us to send all network requests through
- // a designated test server.
- if (command_line.HasSwitch(switches::kFixedHost)) {
- std::string host =
- command_line.GetSwitchValueASCII(switches::kFixedHost);
- global_host_resolver = new net::FixedHostResolver(host);
- } else {
- global_host_resolver = net::CreateSystemHostResolver();
-
- if (command_line.HasSwitch(switches::kDisableIPv6))
- global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
- }
-
- global_host_resolver->AddRef(); // Balanced by EnsureDnsPrefetchShutdown().
- }
- return global_host_resolver;
+net::HostResolver::Observer* CreatePrefetchObserver() {
+ return new PrefetchObserver();
}
//------------------------------------------------------------------------------
@@ -513,7 +461,7 @@ static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
return;
}
- Singleton<PrefetchObserver>::get()->GetInitialDnsResolutionList(startup_list);
+ g_prefetch_observer->GetInitialDnsResolutionList(startup_list);
// TODO(jar): Trimming should be done more regularly, such as every 48 hours
// of physical time, or perhaps after 48 hours of running (excluding time
@@ -546,8 +494,8 @@ void SaveDnsPrefetchStateForNextStartupAndTrim(PrefService* prefs) {
completion.Wait();
}
-static void DnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
- PrefService* local_state) {
+static NameList GetDnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
+ PrefService* local_state) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
NameList hostnames;
// Prefetch DNS for hostnames we learned about during last session.
@@ -578,36 +526,10 @@ static void DnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
}
}
- if (hostnames.size() > 0)
- DnsPrefetchMotivatedList(hostnames, DnsHostInfo::STARTUP_LIST_MOTIVATED);
- else // Start a thread.
- DnsMotivatedPrefetch(std::string("www.google.com"),
- DnsHostInfo::STARTUP_LIST_MOTIVATED);
-}
-
-//------------------------------------------------------------------------------
-// Functions to persist and restore host references, that are used to direct DNS
-// prefetch of names (probably) used in subresources when the major resource is
-// navigated towards.
+ if (hostnames.empty())
+ hostnames.push_back("www.google.com");
-static void RestoreSubresourceReferrers(PrefService* local_state) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
-
- if (NULL == dns_master)
- return;
- ListValue* referral_list =
- local_state->GetMutableList(prefs::kDnsHostReferralList);
-
- // Deleted after deserialization has completed on IO thread.
- ListValue* referral_list_copy =
- static_cast<ListValue*>(referral_list->DeepCopy());
-
- ChromeThread::PostTask(
- ChromeThread::IO,
- FROM_HERE,
- NewRunnableMethod(dns_master,
- &DnsMaster::DeserializeReferrersThenDelete,
- referral_list_copy));
+ return hostnames;
}
//------------------------------------------------------------------------------
@@ -667,16 +589,9 @@ DnsGlobalInit::DnsGlobalInit(PrefService* user_prefs,
TimeDelta::FromMilliseconds(max_queueing_delay_ms));
DCHECK(!dns_master);
- InitDnsPrefetch(max_queueing_delay, max_concurrent, user_prefs);
- DCHECK(dns_master); // Will be checked in destructor.
- DnsPrefetchHostNamesAtStartup(user_prefs, local_state);
- RestoreSubresourceReferrers(local_state);
+ InitDnsPrefetch(max_queueing_delay, max_concurrent, user_prefs,
+ local_state);
}
}
-DnsGlobalInit::~DnsGlobalInit() {
- if (dns_master)
- FreeDnsPrefetchResources();
- }
-
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_global.h b/chrome/browser/net/dns_global.h
index 48d7a56..bc44b79 100644
--- a/chrome/browser/net/dns_global.h
+++ b/chrome/browser/net/dns_global.h
@@ -17,31 +17,25 @@
#include "base/field_trial.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/net/dns_master.h"
+#include "net/base/host_resolver.h"
class PrefService;
-namespace net {
-class HostResolver;
-}
-
namespace chrome_browser_net {
-// Initialize dns prefetching subsystem. Must be called before any other
-// functions.
-void InitDnsPrefetch(TimeDelta max_queue_delay, size_t max_concurrent,
- PrefService* user_prefs);
-
-// Cancel pending lookup requests and don't make new ones. Does nothing
-// if dns prefetching has not been initialized (to simplify its usage).
-void EnsureDnsPrefetchShutdown();
+// Deletes |referral_list| when done.
+void FinalizeDnsPrefetchInitialization(
+ DnsMaster* global_dns_master,
+ net::HostResolver::Observer* global_prefetch_observer,
+ const NameList& hostnames_to_prefetch,
+ ListValue* referral_list);
-// Free all resources allocated by InitDnsPrefetch. After that you must not call
-// any function from this file.
+// Free all resources allocated by FinalizeDnsPrefetchInitialization. After that
+// you must not call any function from this file.
void FreeDnsPrefetchResources();
-// Lazily allocates a HostResolver to be used by the DNS prefetch system, on
-// the IO thread.
-net::HostResolver* GetGlobalHostResolver();
+// Creates the HostResolver observer for the prefetching system.
+net::HostResolver::Observer* CreatePrefetchObserver();
//------------------------------------------------------------------------------
// Global APIs relating to Prefetching in browser
@@ -70,7 +64,6 @@ class DnsGlobalInit {
static const int kMaxPrefetchQueueingDelayMs;
DnsGlobalInit(PrefService* user_prefs, PrefService* local_state);
- ~DnsGlobalInit();
private:
// Maintain a field trial instance when we do A/B testing.
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h
index 913d579..b665358 100644
--- a/chrome/browser/net/dns_master.h
+++ b/chrome/browser/net/dns_master.h
@@ -29,7 +29,7 @@ using base::TimeDelta;
namespace net {
class HostResolver;
-}
+} // namespace net
namespace chrome_browser_net {
diff --git a/chrome/browser/net/ssl_config_service_manager_pref.cc b/chrome/browser/net/ssl_config_service_manager_pref.cc
index 57cf83f..822e4ac 100644
--- a/chrome/browser/net/ssl_config_service_manager_pref.cc
+++ b/chrome/browser/net/ssl_config_service_manager_pref.cc
@@ -5,6 +5,7 @@
#include "base/message_loop.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
index ae507fa..969c17b 100644
--- a/chrome/browser/process_singleton_linux.cc
+++ b/chrome/browser/process_singleton_linux.cc
@@ -64,6 +64,7 @@
#if defined(TOOLKIT_GTK)
#include "chrome/browser/gtk/process_singleton_dialog.h"
#endif
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/common/chrome_constants.h"
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index b7bdb83..fad8eb5 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/history/history.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/url_request_context_getter.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/profile.h"
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a21a4c8..76c622b 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -211,6 +211,8 @@
'browser/browser_process.h',
'browser/browser_process_impl.cc',
'browser/browser_process_impl.h',
+ 'browser/browser_process_sub_thread.cc',
+ 'browser/browser_process_sub_thread.h',
'browser/browser_shutdown.cc',
'browser/browser_shutdown.h',
'browser/browser_theme_pack.cc',
@@ -1135,6 +1137,8 @@
'browser/input_window_dialog_win.cc',
'browser/intranet_redirect_detector.cc',
'browser/intranet_redirect_detector.h',
+ 'browser/io_thread.cc',
+ 'browser/io_thread.h',
'browser/jankometer.cc',
'browser/jankometer.h',
'browser/jumplist.cc',
diff --git a/chrome/test/in_process_browser_test.cc b/chrome/test/in_process_browser_test.cc
index 4e206e8..d71a93a 100644
--- a/chrome/test/in_process_browser_test.cc
+++ b/chrome/test/in_process_browser_test.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/intranet_redirect_detector.h"
+#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
diff --git a/chrome/test/testing_browser_process.h b/chrome/test/testing_browser_process.h
index 2bbcdcb..62dc8a9 100644
--- a/chrome/test/testing_browser_process.h
+++ b/chrome/test/testing_browser_process.h
@@ -20,6 +20,8 @@
#include "chrome/browser/browser_process.h"
#include "chrome/common/notification_service.h"
+class IOThread;
+
class TestingBrowserProcess : public BrowserProcess {
public:
TestingBrowserProcess()
@@ -40,7 +42,7 @@ class TestingBrowserProcess : public BrowserProcess {
return NULL;
}
- virtual base::Thread* io_thread() {
+ virtual IOThread* io_thread() {
return NULL;
}
diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc
index dcb37a3..152798d 100644
--- a/chrome/test/ui/ui_test.cc
+++ b/chrome/test/ui/ui_test.cc
@@ -1493,4 +1493,3 @@ void UITest::TearDown() {
UITestBase::TearDown();
PlatformTest::TearDown();
}
-