Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/browser_main.h" | 5 #include "content/public/browser/browser_main_runner.h" |
| 6 | 6 |
| 7 #include "base/allocator/allocator_shim.h" | 7 #include "base/allocator/allocator_shim.h" |
| 8 #include "base/base_switches.h" | 8 #include "base/base_switches.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "content/browser/browser_main_loop.h" | 13 #include "content/browser/browser_main_loop.h" |
| 14 #include "content/browser/notification_service_impl.h" | 14 #include "content/browser/notification_service_impl.h" |
| 15 #include "content/common/child_process.h" | 15 #include "content/common/child_process.h" |
| 16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
| 17 #include "content/public/common/main_function_params.h" | 17 #include "content/public/common/main_function_params.h" |
| 18 | 18 |
| 19 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
| 20 #include "base/win/scoped_com_initializer.h" | 20 #include "base/win/scoped_com_initializer.h" |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 bool g_exited_main_message_loop = false; | 25 bool g_exited_main_message_loop = false; |
| 26 | 26 |
| 27 class BrowserMainRunnerImpl : public content::BrowserMainRunner { | |
| 28 public: | |
| 29 BrowserMainRunnerImpl() | |
| 30 : is_initialized_(false), | |
| 31 is_shutdown_(false) { | |
| 32 } | |
| 33 | |
| 34 ~BrowserMainRunnerImpl() { | |
| 35 if (is_initialized_ && !is_shutdown_) | |
| 36 Shutdown(); | |
| 37 } | |
| 38 | |
| 39 virtual int Initialize(const content::MainFunctionParams& parameters) | |
| 40 OVERRIDE { | |
| 41 is_initialized_ = true; | |
| 42 | |
| 43 // ChildProcess:: is a misnomer unless you consider context. Use | |
| 44 // of --wait-for-debugger only makes sense when Chrome itself is a | |
| 45 // child process (e.g. when launched by PyAuto). | |
| 46 if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) | |
| 47 ChildProcess::WaitForDebugger("Browser"); | |
| 48 | |
| 49 notification_service_.reset(new NotificationServiceImpl); | |
| 50 | |
| 51 main_loop_.reset(new content::BrowserMainLoop(parameters)); | |
| 52 | |
| 53 main_loop_->Init(); | |
| 54 | |
| 55 main_loop_->EarlyInitialization(); | |
| 56 | |
| 57 // Must happen before we try to use a message loop or display any UI. | |
| 58 main_loop_->InitializeToolkit(); | |
| 59 | |
| 60 main_loop_->MainMessageLoopStart(); | |
| 61 | |
| 62 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here | |
| 63 // are NOT deleted. If you need something to run during WM_ENDSESSION add it | |
| 64 // to browser_shutdown::Shutdown or BrowserProcess::EndSession. | |
| 65 | |
| 66 // !!!!!!!!!! READ ME !!!!!!!!!! | |
|
jam
2012/02/01 17:28:39
actually this comment is so out of date especially
Marshall
2012/02/01 19:37:14
Done.
| |
| 67 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you | |
| 68 // need to add something above this comment, read the documentation in | |
| 69 // browser_main.h. If you need to add something below, please do the | |
| 70 // following: | |
| 71 // - Figure out where you should add your code. Do NOT just pick a random | |
| 72 // location "which works". | |
| 73 // - Document the dependencies apart from compile-time-checkable ones. What | |
| 74 // must happen before your new code is executed? Does your new code need | |
| 75 // to run before something else? Are there performance reasons for | |
| 76 // executing your code at that point? | |
| 77 // - If you need to create a (persistent) object, heap allocate it and keep | |
| 78 // a |scoped_ptr| to it rather than allocating it on the stack. Otherwise | |
| 79 // I'll have to convert your code when I refactor. | |
| 80 // - Unless your new code is just a couple of lines, factor it out into a | |
| 81 // function with a well-defined purpose. Do NOT just add it inline in | |
| 82 // |BrowserMain()|. | |
| 83 // Thanks! | |
| 84 | |
| 85 // TODO(viettrungluu): put the remainder into BrowserMainParts | |
| 86 | |
| 87 #if defined(OS_WIN) | |
| 88 #if !defined(NO_TCMALLOC) | |
| 89 // When linking shared libraries, NO_TCMALLOC is defined, and dynamic | |
| 90 // allocator selection is not supported. | |
| 91 | |
| 92 // Make this call before going multithreaded, or spawning any subprocesses. | |
| 93 base::allocator::SetupSubprocessAllocator(); | |
| 94 #endif | |
| 95 | |
| 96 com_initializer_.reset(new base::win::ScopedCOMInitializer); | |
| 97 #endif // OS_WIN | |
| 98 | |
| 99 statistics_.reset(new base::StatisticsRecorder); | |
| 100 | |
| 101 main_loop_->CreateThreads(); | |
| 102 | |
| 103 // Return -1 to indicate no early termination. | |
| 104 return -1; | |
| 105 } | |
| 106 | |
| 107 virtual int Run() OVERRIDE { | |
| 108 DCHECK(is_initialized_); | |
| 109 DCHECK(!is_shutdown_); | |
| 110 main_loop_->RunMainMessageLoopParts(); | |
| 111 return main_loop_->GetResultCode(); | |
| 112 } | |
| 113 | |
| 114 virtual void Shutdown() OVERRIDE { | |
| 115 DCHECK(is_initialized_); | |
| 116 DCHECK(!is_shutdown_); | |
| 117 g_exited_main_message_loop = true; | |
| 118 main_loop_->ShutdownThreadsAndCleanUp(); | |
| 119 | |
| 120 statistics_.reset(NULL); | |
| 121 | |
| 122 #if defined(OS_WIN) | |
| 123 com_initializer_.reset(NULL); | |
| 124 #endif | |
| 125 | |
| 126 main_loop_.reset(NULL); | |
| 127 | |
| 128 notification_service_.reset(NULL); | |
| 129 | |
| 130 is_shutdown_ = true; | |
| 131 } | |
| 132 | |
| 133 protected: | |
| 134 // True if the runner has been initialized. | |
| 135 bool is_initialized_; | |
| 136 | |
| 137 // True if the runner has been shut down. | |
| 138 bool is_shutdown_; | |
| 139 | |
| 140 scoped_ptr<NotificationServiceImpl> notification_service_; | |
| 141 scoped_ptr<content::BrowserMainLoop> main_loop_; | |
| 142 #if defined(OS_WIN) | |
| 143 scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_; | |
| 144 #endif | |
| 145 scoped_ptr<base::StatisticsRecorder> statistics_; | |
| 146 | |
| 147 DISALLOW_COPY_AND_ASSIGN(BrowserMainRunnerImpl); | |
| 148 }; | |
| 149 | |
| 27 } // namespace | 150 } // namespace |
| 28 | 151 |
| 29 namespace content { | 152 namespace content { |
| 30 | 153 |
| 154 // static | |
| 155 BrowserMainRunner* BrowserMainRunner::Create() { | |
| 156 return new BrowserMainRunnerImpl(); | |
| 157 } | |
| 158 | |
| 31 bool ExitedMainMessageLoop() { | 159 bool ExitedMainMessageLoop() { |
| 32 return g_exited_main_message_loop; | 160 return g_exited_main_message_loop; |
| 33 } | 161 } |
| 34 | 162 |
| 35 } // namespace content | 163 } // namespace content |
| 36 | |
| 37 // Main routine for running as the Browser process. | |
| 38 int BrowserMain(const content::MainFunctionParams& parameters) { | |
| 39 TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, ""); | |
| 40 | |
| 41 // ChildProcess:: is a misnomer unless you consider context. Use | |
| 42 // of --wait-for-debugger only makes sense when Chrome itself is a | |
| 43 // child process (e.g. when launched by PyAuto). | |
| 44 if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) | |
| 45 ChildProcess::WaitForDebugger("Browser"); | |
| 46 | |
| 47 NotificationServiceImpl main_notification_service; | |
| 48 | |
| 49 scoped_ptr<content::BrowserMainLoop> main_loop( | |
| 50 new content::BrowserMainLoop(parameters)); | |
| 51 | |
| 52 main_loop->Init(); | |
| 53 | |
| 54 main_loop->EarlyInitialization(); | |
| 55 | |
| 56 // Must happen before we try to use a message loop or display any UI. | |
| 57 main_loop->InitializeToolkit(); | |
| 58 | |
| 59 main_loop->MainMessageLoopStart(); | |
| 60 | |
| 61 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here | |
| 62 // are NOT deleted. If you need something to run during WM_ENDSESSION add it | |
| 63 // to browser_shutdown::Shutdown or BrowserProcess::EndSession. | |
| 64 | |
| 65 // !!!!!!!!!! READ ME !!!!!!!!!! | |
| 66 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you | |
| 67 // need to add something above this comment, read the documentation in | |
| 68 // browser_main.h. If you need to add something below, please do the | |
| 69 // following: | |
| 70 // - Figure out where you should add your code. Do NOT just pick a random | |
| 71 // location "which works". | |
| 72 // - Document the dependencies apart from compile-time-checkable ones. What | |
| 73 // must happen before your new code is executed? Does your new code need to | |
| 74 // run before something else? Are there performance reasons for executing | |
| 75 // your code at that point? | |
| 76 // - If you need to create a (persistent) object, heap allocate it and keep a | |
| 77 // |scoped_ptr| to it rather than allocating it on the stack. Otherwise | |
| 78 // I'll have to convert your code when I refactor. | |
| 79 // - Unless your new code is just a couple of lines, factor it out into a | |
| 80 // function with a well-defined purpose. Do NOT just add it inline in | |
| 81 // |BrowserMain()|. | |
| 82 // Thanks! | |
| 83 | |
| 84 // TODO(viettrungluu): put the remainder into BrowserMainParts | |
| 85 | |
| 86 #if defined(OS_WIN) | |
| 87 #if !defined(NO_TCMALLOC) | |
| 88 // When linking shared libraries, NO_TCMALLOC is defined, and dynamic | |
| 89 // allocator selection is not supported. | |
| 90 | |
| 91 // Make this call before going multithreaded, or spawning any subprocesses. | |
| 92 base::allocator::SetupSubprocessAllocator(); | |
| 93 #endif | |
| 94 | |
| 95 base::win::ScopedCOMInitializer com_initializer; | |
| 96 #endif // OS_WIN | |
| 97 | |
| 98 base::StatisticsRecorder statistics; | |
| 99 | |
| 100 main_loop->RunMainMessageLoopParts(&g_exited_main_message_loop); | |
| 101 | |
| 102 TRACE_EVENT_END_ETW("BrowserMain", 0, 0); | |
| 103 | |
| 104 return main_loop->GetResultCode(); | |
| 105 } | |
| OLD | NEW |