diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-22 17:46:27 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-22 17:46:27 +0000 |
commit | 0ac8368b361a5edbcfe4b985131a8eec13304f49 (patch) | |
tree | fbc7e4bdb86150f112730932c0d9d97fab16f4e0 /chrome | |
parent | 290da7ba0368e3cf1dbbe214a5be9f89666954d0 (diff) | |
download | chromium_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')
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(); } - |