Index: content/browser/browser_main_runner.cc |
=================================================================== |
--- content/browser/browser_main_runner.cc (revision 121246) |
+++ content/browser/browser_main_runner.cc (working copy) |
@@ -1,8 +1,8 @@ |
-// 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 "content/public/browser/browser_main_runner.h" |
#include "base/allocator/allocator_shim.h" |
#include "base/base_switches.h" |
@@ -20,86 +20,129 @@ |
#include "base/win/scoped_com_initializer.h" |
#endif |
+bool g_exited_main_message_loop = false; |
+ |
namespace { |
-bool g_exited_main_message_loop = false; |
+class BrowserMainRunnerImpl : public content::BrowserMainRunner { |
+ public: |
+ BrowserMainRunnerImpl() |
+ : is_initialized_(false), |
+ is_shutdown_(false), |
+ created_threads_(false) { |
+ } |
-} // namespace |
+ ~BrowserMainRunnerImpl() { |
+ if (is_initialized_ && !is_shutdown_) |
+ Shutdown(); |
+ } |
-namespace content { |
+ virtual int Initialize(const content::MainFunctionParams& parameters) |
+ OVERRIDE { |
+ is_initialized_ = true; |
-bool ExitedMainMessageLoop() { |
- return g_exited_main_message_loop; |
-} |
+ // 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"); |
-} // namespace content |
+ notification_service_.reset(new NotificationServiceImpl); |
-// Main routine for running as the Browser process. |
-int BrowserMain(const content::MainFunctionParams& parameters) { |
- TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, ""); |
+ main_loop_.reset(new content::BrowserMainLoop(parameters)); |
- // 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"); |
+ main_loop_->Init(); |
- NotificationServiceImpl main_notification_service; |
+ main_loop_->EarlyInitialization(); |
- scoped_ptr<content::BrowserMainLoop> main_loop( |
- new content::BrowserMainLoop(parameters)); |
+ // Must happen before we try to use a message loop or display any UI. |
+ main_loop_->InitializeToolkit(); |
- main_loop->Init(); |
+ main_loop_->MainMessageLoopStart(); |
- main_loop->EarlyInitialization(); |
+ // 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. |
- // Must happen before we try to use a message loop or display any UI. |
- main_loop->InitializeToolkit(); |
+#if defined(OS_WIN) |
+#if !defined(NO_TCMALLOC) |
+ // When linking shared libraries, NO_TCMALLOC is defined, and dynamic |
+ // allocator selection is not supported. |
- main_loop->MainMessageLoopStart(); |
+ // Make this call before going multithreaded, or spawning any subprocesses. |
+ base::allocator::SetupSubprocessAllocator(); |
+#endif |
- // 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. |
+ com_initializer_.reset(new base::win::ScopedCOMInitializer); |
+#endif // OS_WIN |
- // !!!!!!!!!! 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! |
+ statistics_.reset(new base::StatisticsRecorder); |
- // TODO(viettrungluu): put the remainder into BrowserMainParts |
+ main_loop_->CreateThreads(); |
+ int result_code = main_loop_->GetResultCode(); |
+ if (result_code > 0) |
+ return result_code; |
+ created_threads_ = true; |
+ // 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; |
+ |
+ if (created_threads_) |
+ main_loop_->ShutdownThreadsAndCleanUp(); |
+ |
+ statistics_.reset(NULL); |
+ |
#if defined(OS_WIN) |
-#if !defined(NO_TCMALLOC) |
- // When linking shared libraries, NO_TCMALLOC is defined, and dynamic |
- // allocator selection is not supported. |
+ com_initializer_.reset(NULL); |
+#endif |
- // Make this call before going multithreaded, or spawning any subprocesses. |
- base::allocator::SetupSubprocessAllocator(); |
+ 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_; |
+ |
+ // True if the non-UI threads were created. |
+ bool created_threads_; |
+ |
+ 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_; |
- base::win::ScopedCOMInitializer com_initializer; |
-#endif // OS_WIN |
+ DISALLOW_COPY_AND_ASSIGN(BrowserMainRunnerImpl); |
+}; |
- base::StatisticsRecorder statistics; |
+} // namespace |
- main_loop->RunMainMessageLoopParts(&g_exited_main_message_loop); |
+namespace content { |
- TRACE_EVENT_END_ETW("BrowserMain", 0, 0); |
+// static |
+BrowserMainRunner* BrowserMainRunner::Create() { |
+ return new BrowserMainRunnerImpl(); |
+} |
- return main_loop->GetResultCode(); |
-} |
+} // namespace content |