diff options
Diffstat (limited to 'content/browser')
-rw-r--r-- | content/browser/browser_main.cc | 97 | ||||
-rw-r--r-- | content/browser/browser_main_loop.cc | 17 | ||||
-rw-r--r-- | content/browser/browser_main_loop.h | 18 | ||||
-rw-r--r-- | content/browser/browser_main_runner.cc | 138 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host_impl.cc | 4 |
5 files changed, 171 insertions, 103 deletions
diff --git a/content/browser/browser_main.cc b/content/browser/browser_main.cc index 0efd4ae..99f8247 100644 --- a/content/browser/browser_main.cc +++ b/content/browser/browser_main.cc @@ -1,105 +1,28 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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 "content/browser/browser_main.h" -#include "base/allocator/allocator_shim.h" -#include "base/base_switches.h" -#include "base/command_line.h" #include "base/debug/trace_event.h" -#include "base/logging.h" -#include "base/metrics/histogram.h" -#include "content/browser/browser_main_loop.h" -#include "content/browser/notification_service_impl.h" -#include "content/common/child_process.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/main_function_params.h" - -#if defined(OS_WIN) -#include "base/win/scoped_com_initializer.h" -#endif - -namespace { - -bool g_exited_main_message_loop = false; - -} // namespace - -namespace content { - -bool ExitedMainMessageLoop() { - return g_exited_main_message_loop; -} - -} // namespace content +#include "content/public/browser/browser_main_runner.h" // Main routine for running as the Browser process. int BrowserMain(const content::MainFunctionParams& parameters) { TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, ""); - // ChildProcess:: is a misnomer unless you consider context. Use - // of --wait-for-debugger only makes sense when Chrome itself is a - // child process (e.g. when launched by PyAuto). - if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) - ChildProcess::WaitForDebugger("Browser"); - - NotificationServiceImpl main_notification_service; - - scoped_ptr<content::BrowserMainLoop> main_loop( - new content::BrowserMainLoop(parameters)); - - main_loop->Init(); - - main_loop->EarlyInitialization(); - - // Must happen before we try to use a message loop or display any UI. - main_loop->InitializeToolkit(); - - main_loop->MainMessageLoopStart(); - - // WARNING: If we get a WM_ENDSESSION, objects created on the stack here - // are NOT deleted. If you need something to run during WM_ENDSESSION add it - // to browser_shutdown::Shutdown or BrowserProcess::EndSession. - - // !!!!!!!!!! READ ME !!!!!!!!!! - // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you - // need to add something above this comment, read the documentation in - // browser_main.h. If you need to add something below, please do the - // following: - // - Figure out where you should add your code. Do NOT just pick a random - // location "which works". - // - Document the dependencies apart from compile-time-checkable ones. What - // must happen before your new code is executed? Does your new code need to - // run before something else? Are there performance reasons for executing - // your code at that point? - // - If you need to create a (persistent) object, heap allocate it and keep a - // |scoped_ptr| to it rather than allocating it on the stack. Otherwise - // I'll have to convert your code when I refactor. - // - Unless your new code is just a couple of lines, factor it out into a - // function with a well-defined purpose. Do NOT just add it inline in - // |BrowserMain()|. - // Thanks! - - // TODO(viettrungluu): put the remainder into BrowserMainParts - -#if defined(OS_WIN) -#if !defined(NO_TCMALLOC) - // When linking shared libraries, NO_TCMALLOC is defined, and dynamic - // allocator selection is not supported. - - // Make this call before going multithreaded, or spawning any subprocesses. - base::allocator::SetupSubprocessAllocator(); -#endif + scoped_ptr<content::BrowserMainRunner> main_runner_( + content::BrowserMainRunner::Create()); - base::win::ScopedCOMInitializer com_initializer; -#endif // OS_WIN + int exit_code = main_runner_->Initialize(parameters); + if (exit_code >= 0) + return exit_code; - base::StatisticsRecorder statistics; + exit_code = main_runner_->Run(); - main_loop->RunMainMessageLoopParts(&g_exited_main_message_loop); + main_runner_->Shutdown(); TRACE_EVENT_END_ETW("BrowserMain", 0, 0); - return main_loop->GetResultCode(); + return exit_code; } diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 563c310..6a9e38c 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -294,7 +294,9 @@ void BrowserMainLoop::MainMessageLoopStart() { // Must first NULL pointer or we hit a DCHECK that the newly constructed // message loop is the current one. main_message_loop_.reset(); - main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); + main_message_loop_.reset(parts_->GetMainMessageLoop()); + if (!main_message_loop_.get()) + main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); InitializeMainThread(); @@ -321,8 +323,7 @@ void BrowserMainLoop::MainMessageLoopStart() { parts_->PostMainMessageLoopStart(); } -void BrowserMainLoop::RunMainMessageLoopParts( - bool* completed_main_message_loop) { +void BrowserMainLoop::CreateThreads() { if (parts_.get()) result_code_ = parts_->PreCreateThreads(); @@ -404,10 +405,13 @@ void BrowserMainLoop::RunMainMessageLoopParts( if (parts_.get()) parts_->PreMainMessageLoopRun(); - TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); // If the UI thread blocks, the whole UI is unresponsive. // Do not allow disk IO from the UI thread. base::ThreadRestrictions::SetIOAllowed(false); +} + +void BrowserMainLoop::RunMainMessageLoopParts() { + TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); bool ran_main_loop = false; if (parts_.get()) @@ -417,11 +421,6 @@ void BrowserMainLoop::RunMainMessageLoopParts( MainMessageLoopRun(); TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); - - if (completed_main_message_loop) - *completed_main_message_loop = true; - - ShutdownThreadsAndCleanUp(); } void BrowserMainLoop::ShutdownThreadsAndCleanUp() { diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index c0c3a45..d6f351d 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -44,24 +44,30 @@ class BrowserMainLoop { void EarlyInitialization(); void InitializeToolkit(); void MainMessageLoopStart(); - void RunMainMessageLoopParts(bool* completed_main_message_loop); - void MainMessageLoopRun(); - int GetResultCode() const { return result_code_; } + // Create all secondary threads. + void CreateThreads(); - private: - // For ShutdownThreadsAndCleanUp. - friend class BrowserShutdownImpl; + // Perform the default message loop run logic. + void RunMainMessageLoopParts(); // Performs the shutdown sequence, starting with PostMainMessageLoopRun // through stopping threads to PostDestroyThreads. void ShutdownThreadsAndCleanUp(); + int GetResultCode() const { return result_code_; } + + private: + // For ShutdownThreadsAndCleanUp. + friend class BrowserShutdownImpl; + void InitializeMainThread(); // Called right after the browser threads have been started. void BrowserThreadsStarted(); + void MainMessageLoopRun(); + // Members initialized on construction --------------------------------------- const content::MainFunctionParams& parameters_; const CommandLine& parsed_command_line_; diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc new file mode 100644 index 0000000..b7aaf74 --- /dev/null +++ b/content/browser/browser_main_runner.cc @@ -0,0 +1,138 @@ +// Copyright (c) 2012 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 "content/public/browser/browser_main_runner.h" + +#include "base/allocator/allocator_shim.h" +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "base/metrics/histogram.h" +#include "content/browser/browser_main_loop.h" +#include "content/browser/notification_service_impl.h" +#include "content/common/child_process.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/main_function_params.h" + +#if defined(OS_WIN) +#include "base/win/scoped_com_initializer.h" +#endif + +bool g_exited_main_message_loop = false; + +namespace { + +class BrowserMainRunnerImpl : public content::BrowserMainRunner { + public: + BrowserMainRunnerImpl() + : is_initialized_(false), + is_shutdown_(false) { + } + + ~BrowserMainRunnerImpl() { + if (is_initialized_ && !is_shutdown_) + Shutdown(); + } + + virtual int Initialize(const content::MainFunctionParams& parameters) + OVERRIDE { + is_initialized_ = true; + + // ChildProcess:: is a misnomer unless you consider context. Use + // of --wait-for-debugger only makes sense when Chrome itself is a + // child process (e.g. when launched by PyAuto). + if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) + ChildProcess::WaitForDebugger("Browser"); + + notification_service_.reset(new NotificationServiceImpl); + + main_loop_.reset(new content::BrowserMainLoop(parameters)); + + main_loop_->Init(); + + main_loop_->EarlyInitialization(); + + // Must happen before we try to use a message loop or display any UI. + main_loop_->InitializeToolkit(); + + main_loop_->MainMessageLoopStart(); + + // WARNING: If we get a WM_ENDSESSION, objects created on the stack here + // are NOT deleted. If you need something to run during WM_ENDSESSION add it + // to browser_shutdown::Shutdown or BrowserProcess::EndSession. + +#if defined(OS_WIN) +#if !defined(NO_TCMALLOC) + // When linking shared libraries, NO_TCMALLOC is defined, and dynamic + // allocator selection is not supported. + + // Make this call before going multithreaded, or spawning any subprocesses. + base::allocator::SetupSubprocessAllocator(); +#endif + + com_initializer_.reset(new base::win::ScopedCOMInitializer); +#endif // OS_WIN + + statistics_.reset(new base::StatisticsRecorder); + + main_loop_->CreateThreads(); + + // Return -1 to indicate no early termination. + return -1; + } + + virtual int Run() OVERRIDE { + DCHECK(is_initialized_); + DCHECK(!is_shutdown_); + main_loop_->RunMainMessageLoopParts(); + return main_loop_->GetResultCode(); + } + + virtual void Shutdown() OVERRIDE { + DCHECK(is_initialized_); + DCHECK(!is_shutdown_); + g_exited_main_message_loop = true; + main_loop_->ShutdownThreadsAndCleanUp(); + + statistics_.reset(NULL); + +#if defined(OS_WIN) + com_initializer_.reset(NULL); +#endif + + main_loop_.reset(NULL); + + notification_service_.reset(NULL); + + is_shutdown_ = true; + } + + protected: + // True if the runner has been initialized. + bool is_initialized_; + + // True if the runner has been shut down. + bool is_shutdown_; + + scoped_ptr<NotificationServiceImpl> notification_service_; + scoped_ptr<content::BrowserMainLoop> main_loop_; +#if defined(OS_WIN) + scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_; +#endif + scoped_ptr<base::StatisticsRecorder> statistics_; + + DISALLOW_COPY_AND_ASSIGN(BrowserMainRunnerImpl); +}; + +} // namespace + +namespace content { + +// static +BrowserMainRunner* BrowserMainRunner::Create() { + return new BrowserMainRunnerImpl(); +} + +} // namespace content diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 7e32b8d..a32dd38 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -121,6 +121,8 @@ using content::ChildProcessHostImpl; using content::UserMetricsAction; using content::WebUIControllerFactory; +extern bool g_exited_main_message_loop; + // This class creates the IO thread for the renderer when running in // single-process mode. It's not used in multi-process mode. class RendererMainThread : public base::Thread { @@ -315,7 +317,7 @@ RenderProcessHostImpl::RenderProcessHostImpl( base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE); - CHECK(!content::ExitedMainMessageLoop()); + CHECK(!g_exited_main_message_loop); RegisterHost(GetID(), this); g_all_hosts.Get().set_check_on_null_data(true); // Initialize |child_process_activity_time_| to a reasonable value. |