| Index: chrome/browser/browser_process_impl.cc
|
| ===================================================================
|
| --- chrome/browser/browser_process_impl.cc (revision 111697)
|
| +++ chrome/browser/browser_process_impl.cc (working copy)
|
| @@ -68,7 +68,7 @@
|
| #include "chrome/common/switch_utils.h"
|
| #include "chrome/common/url_constants.h"
|
| #include "chrome/installer/util/google_update_constants.h"
|
| -#include "content/browser/browser_child_process_host.h"
|
| +#include "content/browser/browser_process_sub_thread.h"
|
| #include "content/browser/child_process_security_policy.h"
|
| #include "content/browser/download/download_file_manager.h"
|
| #include "content/browser/download/download_status_updater.h"
|
| @@ -124,7 +124,15 @@
|
| BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line)
|
| : created_resource_dispatcher_host_(false),
|
| created_metrics_service_(false),
|
| + created_io_thread_(false),
|
| + created_file_thread_(false),
|
| + created_db_thread_(false),
|
| + created_process_launcher_thread_(false),
|
| + created_cache_thread_(false),
|
| created_watchdog_thread_(false),
|
| +#if defined(OS_CHROMEOS)
|
| + created_web_socket_proxy_thread_(false),
|
| +#endif
|
| created_profile_manager_(false),
|
| created_local_state_(false),
|
| created_icon_manager_(false),
|
| @@ -157,20 +165,12 @@
|
| }
|
|
|
| BrowserProcessImpl::~BrowserProcessImpl() {
|
| - // See StartTearDown and PreStopThread functions below, this is where
|
| - // most destruction happens so that it can be interleaved with threads
|
| - // going away.
|
| +#if defined(OS_CHROMEOS)
|
| + if (web_socket_proxy_thread_.get())
|
| + chromeos::WebSocketProxyController::Shutdown();
|
| + web_socket_proxy_thread_.reset();
|
| +#endif
|
|
|
| - // Wait for the pending print jobs to finish.
|
| - print_job_manager_->OnQuit();
|
| - print_job_manager_.reset();
|
| -
|
| - tracked_objects::ThreadData::EnsureCleanupWasCalled(4);
|
| -
|
| - g_browser_process = NULL;
|
| -}
|
| -
|
| -void BrowserProcessImpl::StartTearDown() {
|
| // Delete the AutomationProviderList before NotificationService,
|
| // since it may try to unregister notifications
|
| // Both NotificationService and AutomationProvider are singleton instances in
|
| @@ -239,65 +239,49 @@
|
|
|
| // Stop the watchdog thread before stopping other threads.
|
| watchdog_thread_.reset();
|
| -}
|
|
|
| -void BrowserProcessImpl::PreStartThread(BrowserThread::ID thread_id) {
|
| - switch (thread_id) {
|
| - case BrowserThread::IO:
|
| - CreateIOThreadState();
|
| - break;
|
| + // Need to stop io_thread_ before resource_dispatcher_host_, since
|
| + // io_thread_ may still deref ResourceDispatcherHost and handle resource
|
| + // request before going away.
|
| + io_thread_.reset();
|
|
|
| - default:
|
| - break;
|
| - }
|
| -}
|
| + // The IO thread was the only user of this thread.
|
| + cache_thread_.reset();
|
|
|
| -void BrowserProcessImpl::PostStartThread(BrowserThread::ID thread_id) {
|
| -}
|
| + // 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.
|
| + process_launcher_thread_.reset();
|
|
|
| -void BrowserProcessImpl::PreStopThread(BrowserThread::ID thread_id) {
|
| - switch (thread_id) {
|
| -#if defined(OS_CHROMEOS)
|
| - case BrowserThread::WEB_SOCKET_PROXY:
|
| - chromeos::WebSocketProxyController::Shutdown();
|
| - break;
|
| -#endif
|
| - case BrowserThread::FILE:
|
| - // Clean up state that lives on or uses the file_thread_ before
|
| - // it goes away.
|
| - if (resource_dispatcher_host_.get()) {
|
| - resource_dispatcher_host()->download_file_manager()->Shutdown();
|
| - resource_dispatcher_host()->save_file_manager()->Shutdown();
|
| - }
|
| - break;
|
| - case BrowserThread::WEBKIT:
|
| - // Need to destroy ResourceDispatcherHost before PluginService
|
| - // and SafeBrowsingService, since it caches a pointer to
|
| - // it. This also causes the webkit thread to terminate (which is
|
| - // still the responsibility of the embedder, not of the content
|
| - // framework).
|
| - resource_dispatcher_host_.reset();
|
| - break;
|
| - default:
|
| - break;
|
| + // Clean up state that lives on the file_thread_ before it goes away.
|
| + if (resource_dispatcher_host_.get()) {
|
| + resource_dispatcher_host()->download_file_manager()->Shutdown();
|
| + resource_dispatcher_host()->save_file_manager()->Shutdown();
|
| }
|
| -}
|
|
|
| -void BrowserProcessImpl::PostStopThread(BrowserThread::ID thread_id) {
|
| - switch (thread_id) {
|
| - case BrowserThread::FILE:
|
| - // With the file_thread_ flushed, we can release any icon resources.
|
| - icon_manager_.reset();
|
| - break;
|
| - case BrowserThread::IO:
|
| - // Reset associated state right after actual thread is stopped,
|
| - // as io_thread_.global_ cleanup happens in CleanUp on the IO
|
| - // thread, i.e. as the thread exits its message loop.
|
| - io_thread_.reset();
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| + // Need to stop the file_thread_ here to force it to process messages in its
|
| + // message loop from the previous call to shutdown the DownloadFileManager,
|
| + // SaveFileManager and SessionService.
|
| + file_thread_.reset();
|
| +
|
| + // With the file_thread_ flushed, we can release any icon resources.
|
| + icon_manager_.reset();
|
| +
|
| + // Need to destroy ResourceDispatcherHost before PluginService and
|
| + // SafeBrowsingService, since it caches a pointer to it. This also
|
| + // causes the webkit thread to terminate.
|
| + resource_dispatcher_host_.reset();
|
| +
|
| + // Wait for the pending print jobs to finish.
|
| + print_job_manager_->OnQuit();
|
| + print_job_manager_.reset();
|
| +
|
| + // Destroy TabCloseableStateWatcher before NotificationService since the
|
| + // former registers for notifications.
|
| + tab_closeable_state_watcher_.reset();
|
| +
|
| + tracked_objects::ThreadData::EnsureCleanupWasCalled(4);
|
| +
|
| + g_browser_process = NULL;
|
| }
|
|
|
| #if defined(OS_WIN)
|
| @@ -411,28 +395,37 @@
|
|
|
| IOThread* BrowserProcessImpl::io_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - DCHECK(io_thread_.get());
|
| + if (!created_io_thread_)
|
| + CreateIOThread();
|
| return io_thread_.get();
|
| }
|
|
|
| base::Thread* BrowserProcessImpl::file_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - return BrowserThread::UnsafeGetBrowserThread(BrowserThread::FILE);
|
| + if (!created_file_thread_)
|
| + CreateFileThread();
|
| + return file_thread_.get();
|
| }
|
|
|
| base::Thread* BrowserProcessImpl::db_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - return BrowserThread::UnsafeGetBrowserThread(BrowserThread::DB);
|
| + if (!created_db_thread_)
|
| + CreateDBThread();
|
| + return db_thread_.get();
|
| }
|
|
|
| base::Thread* BrowserProcessImpl::process_launcher_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - return BrowserThread::UnsafeGetBrowserThread(BrowserThread::PROCESS_LAUNCHER);
|
| + if (!created_process_launcher_thread_)
|
| + CreateProcessLauncherThread();
|
| + return process_launcher_thread_.get();
|
| }
|
|
|
| base::Thread* BrowserProcessImpl::cache_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - return BrowserThread::UnsafeGetBrowserThread(BrowserThread::CACHE);
|
| + if (!created_cache_thread_)
|
| + CreateCacheThread();
|
| + return cache_thread_.get();
|
| }
|
|
|
| WatchDogThread* BrowserProcessImpl::watchdog_thread() {
|
| @@ -446,7 +439,10 @@
|
| #if defined(OS_CHROMEOS)
|
| base::Thread* BrowserProcessImpl::web_socket_proxy_thread() {
|
| DCHECK(CalledOnValidThread());
|
| - return BrowserThread::UnsafeGetBrowserThread(BrowserThread::WEB_SOCKET_PROXY);
|
| + if (!created_web_socket_proxy_thread_)
|
| + CreateWebSocketProxyThread();
|
| + DCHECK(web_socket_proxy_thread_.get() != NULL);
|
| + return web_socket_proxy_thread_.get();
|
| }
|
| #endif
|
|
|
| @@ -646,10 +642,7 @@
|
| }
|
|
|
| bool BrowserProcessImpl::plugin_finder_disabled() const {
|
| - if (plugin_finder_disabled_pref_.get())
|
| - return plugin_finder_disabled_pref_->GetValue();
|
| - else
|
| - return false;
|
| + return *plugin_finder_disabled_pref_;
|
| }
|
|
|
| void BrowserProcessImpl::Observe(int type,
|
| @@ -764,11 +757,14 @@
|
| metrics_service_.reset(new MetricsService);
|
| }
|
|
|
| -void BrowserProcessImpl::CreateIOThreadState() {
|
| - // Prior to any processing happening on the io thread, we create the
|
| - // plugin service as it is predominantly used from the io thread,
|
| - // but must be created on the main thread. The service ctor is
|
| - // inexpensive and does not invoke the io_thread() accessor.
|
| +void BrowserProcessImpl::CreateIOThread() {
|
| + DCHECK(!created_io_thread_ && io_thread_.get() == NULL);
|
| + created_io_thread_ = true;
|
| +
|
| + // Prior to starting the io thread, we create the plugin service as
|
| + // it is predominantly used from the io thread, but must be created
|
| + // on the main thread. The service ctor is inexpensive and does not
|
| + // invoke the io_thread() accessor.
|
| PluginService* plugin_service = PluginService::GetInstance();
|
| plugin_service->Init();
|
| plugin_service->set_filter(ChromePluginServiceFilter::GetInstance());
|
| @@ -793,9 +789,83 @@
|
|
|
| scoped_ptr<IOThread> thread(new IOThread(
|
| local_state(), net_log_.get(), extension_event_router_forwarder_.get()));
|
| + base::Thread::Options options;
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| + if (!thread->StartWithOptions(options))
|
| + return;
|
| io_thread_.swap(thread);
|
| }
|
|
|
| +void BrowserProcessImpl::CreateFileThread() {
|
| + DCHECK(!created_file_thread_ && file_thread_.get() == NULL);
|
| + created_file_thread_ = true;
|
| +
|
| + scoped_ptr<base::Thread> thread(
|
| + new content::BrowserProcessSubThread(BrowserThread::FILE));
|
| + base::Thread::Options options;
|
| +#if defined(OS_WIN)
|
| + // On Windows, the FILE thread needs to be have a UI message loop which pumps
|
| + // messages in such a way that Google Update can communicate back to us.
|
| + options.message_loop_type = MessageLoop::TYPE_UI;
|
| +#else
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| +#endif
|
| + if (!thread->StartWithOptions(options))
|
| + return;
|
| + file_thread_.swap(thread);
|
| +}
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| +void BrowserProcessImpl::CreateWebSocketProxyThread() {
|
| + DCHECK(!created_web_socket_proxy_thread_);
|
| + DCHECK(web_socket_proxy_thread_.get() == NULL);
|
| + created_web_socket_proxy_thread_ = true;
|
| +
|
| + scoped_ptr<base::Thread> thread(
|
| + new content::BrowserProcessSubThread(BrowserThread::WEB_SOCKET_PROXY));
|
| + base::Thread::Options options;
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| + if (!thread->StartWithOptions(options))
|
| + return;
|
| + web_socket_proxy_thread_.swap(thread);
|
| +}
|
| +#endif
|
| +
|
| +void BrowserProcessImpl::CreateDBThread() {
|
| + DCHECK(!created_db_thread_ && db_thread_.get() == NULL);
|
| + created_db_thread_ = true;
|
| +
|
| + scoped_ptr<base::Thread> thread(
|
| + new content::BrowserProcessSubThread(BrowserThread::DB));
|
| + if (!thread->Start())
|
| + return;
|
| + db_thread_.swap(thread);
|
| +}
|
| +
|
| +void BrowserProcessImpl::CreateProcessLauncherThread() {
|
| + DCHECK(!created_process_launcher_thread_ && !process_launcher_thread_.get());
|
| + created_process_launcher_thread_ = true;
|
| +
|
| + scoped_ptr<base::Thread> thread(
|
| + new content::BrowserProcessSubThread(BrowserThread::PROCESS_LAUNCHER));
|
| + if (!thread->Start())
|
| + return;
|
| + process_launcher_thread_.swap(thread);
|
| +}
|
| +
|
| +void BrowserProcessImpl::CreateCacheThread() {
|
| + DCHECK(!created_cache_thread_ && !cache_thread_.get());
|
| + created_cache_thread_ = true;
|
| +
|
| + scoped_ptr<base::Thread> thread(
|
| + new content::DeprecatedBrowserThread(BrowserThread::CACHE));
|
| + base::Thread::Options options;
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| + if (!thread->StartWithOptions(options))
|
| + return;
|
| + cache_thread_.swap(thread);
|
| +}
|
| +
|
| void BrowserProcessImpl::CreateWatchdogThread() {
|
| DCHECK(!created_watchdog_thread_ && watchdog_thread_.get() == NULL);
|
| created_watchdog_thread_ = true;
|
| @@ -841,10 +911,9 @@
|
| // Initialize the preference for the plugin finder policy.
|
| // This preference is only needed on the IO thread so make it available there.
|
| local_state_->RegisterBooleanPref(prefs::kDisablePluginFinder, false);
|
| - plugin_finder_disabled_pref_.reset(new BooleanPrefMember);
|
| - plugin_finder_disabled_pref_->Init(prefs::kDisablePluginFinder,
|
| + plugin_finder_disabled_pref_.Init(prefs::kDisablePluginFinder,
|
| local_state_.get(), NULL);
|
| - plugin_finder_disabled_pref_->MoveToThread(BrowserThread::IO);
|
| + plugin_finder_disabled_pref_.MoveToThread(BrowserThread::IO);
|
|
|
| // Another policy that needs to be defined before the net subsystem is
|
| // initialized is MaxConnectionsPerProxy so we do it here.
|
|
|