Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(699)

Side by Side Diff: content/browser/browser_main_loop.cc

Issue 8302016: Make GTK and Aura parts orthogonal to OS parts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/browser_main_loop.h ('k') | content/browser/mock_content_browser_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/browser/browser_main_loop.h"
6 6
7 #include "base/allocator/allocator_shim.h"
8 #include "base/command_line.h" 7 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h"
11 #include "base/metrics/field_trial.h" 11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/system_monitor/system_monitor.h"
14 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
15 #include "base/tracked_objects.h" 14 #include "base/tracked_objects.h"
16 #include "content/browser/browser_thread.h" 15 #include "content/browser/browser_thread.h"
17 #include "content/browser/notification_service_impl.h"
18 #include "content/common/hi_res_timer_manager.h" 16 #include "content/common/hi_res_timer_manager.h"
19 #include "content/common/main_function_params.h" 17 #include "content/common/main_function_params.h"
20 #include "content/common/sandbox_policy.h" 18 #include "content/common/sandbox_policy.h"
19 #include "content/public/browser/browser_main_parts.h"
21 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/common/content_switches.h" 21 #include "content/public/common/content_switches.h"
23 #include "content/public/common/result_codes.h" 22 #include "content/public/common/result_codes.h"
24 #include "crypto/nss_util.h" 23 #include "crypto/nss_util.h"
25 #include "net/base/network_change_notifier.h" 24 #include "net/base/network_change_notifier.h"
26 #include "net/base/ssl_config_service.h" 25 #include "net/base/ssl_config_service.h"
27 #include "net/socket/client_socket_factory.h" 26 #include "net/socket/client_socket_factory.h"
28 #include "net/socket/tcp_client_socket.h" 27 #include "net/socket/tcp_client_socket.h"
29 28
30 #if defined(OS_WIN) 29 #if defined(OS_WIN)
31 #include <windows.h> 30 #include <windows.h>
32 #include <commctrl.h> 31 #include <commctrl.h>
33 #include <ole2.h> 32 #include <ole2.h>
34 #include <shellapi.h> 33 #include <shellapi.h>
35 34
36 #include "base/win/scoped_com_initializer.h" 35 #include "ui/base/l10n/l10n_util_win.h"
37 #include "net/base/winsock_init.h" 36 #include "net/base/winsock_init.h"
38 #include "sandbox/src/sandbox.h"
39 #include "ui/base/l10n/l10n_util_win.h"
40 #endif 37 #endif
41 38
42 #if defined(OS_LINUX) 39 #if defined(OS_LINUX)
43 #include <glib-object.h> 40 #include <glib-object.h>
44 #endif 41 #endif
45 42
46 #if defined(OS_CHROMEOS) 43 #if defined(OS_CHROMEOS)
47 #include <dbus/dbus-glib.h> 44 #include <dbus/dbus-glib.h>
48 #endif 45 #endif
49 46
50 #if defined(OS_POSIX) && !defined(OS_MACOSX)
51 #include <sys/stat.h>
52
53 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
54 #include "content/browser/zygote_host_linux.h"
55 #endif
56
57 #if defined(TOOLKIT_USES_GTK) 47 #if defined(TOOLKIT_USES_GTK)
58 #include "ui/gfx/gtk_util.h" 48 #include "ui/gfx/gtk_util.h"
59 #endif 49 #endif
60 50
51 #if defined(OS_POSIX) && !defined(OS_MACOSX)
52 #include <sys/stat.h>
53 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
54 #include "content/browser/zygote_host_linux.h"
55 #endif
56
61 namespace { 57 namespace {
62 58
63 #if defined(OS_WIN) 59 #if defined(OS_POSIX) && !defined(OS_MACOSX)
64 // Windows-specific initialization code for the sandbox broker services.
65 void InitializeBrokerServices(const MainFunctionParams& parameters,
66 const CommandLine& parsed_command_line) {
67 sandbox::BrokerServices* broker_services =
68 parameters.sandbox_info_.BrokerServices();
69 if (broker_services) {
70 sandbox::InitBrokerServices(broker_services);
71 if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) {
72 bool use_winsta = !parsed_command_line.HasSwitch(
73 switches::kDisableAltWinstation);
74 // Precreate the desktop and window station used by the renderers.
75 sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
76 sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
77 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
78 policy->Release();
79 }
80 }
81 }
82 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
83 void SetupSandbox(const CommandLine& parsed_command_line) { 60 void SetupSandbox(const CommandLine& parsed_command_line) {
84 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this 61 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this
85 // code en masse out of chrome_main for now. 62 // code en masse out of chrome_main for now.
86 const char* sandbox_binary = NULL; 63 const char* sandbox_binary = NULL;
87 struct stat st; 64 struct stat st;
88 65
89 // In Chromium branded builds, developers can set an environment variable to 66 // In Chromium branded builds, developers can set an environment variable to
90 // use the development sandbox. See 67 // use the development sandbox. See
91 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment 68 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
92 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) 69 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid())
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 GLibLogHandler, 137 GLibLogHandler,
161 NULL); 138 NULL);
162 } 139 }
163 } 140 }
164 #endif 141 #endif
165 142
166 } // namespace 143 } // namespace
167 144
168 namespace content { 145 namespace content {
169 146
170 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) 147
148 // BrowserMainLoop construction / destructione =============================
149
150 BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
171 : parameters_(parameters), 151 : parameters_(parameters),
172 parsed_command_line_(parameters.command_line_), 152 parsed_command_line_(parameters.command_line_),
173 result_code_(content::RESULT_CODE_NORMAL_EXIT) { 153 result_code_(content::RESULT_CODE_NORMAL_EXIT) {
174 #if defined(OS_WIN) 154 #if defined(OS_WIN)
175 OleInitialize(NULL); 155 OleInitialize(NULL);
176 #endif 156 #endif
177 } 157 }
178 158
179 BrowserMainParts::~BrowserMainParts() { 159 BrowserMainLoop::~BrowserMainLoop() {
160 // Destroy added parts in reverse order.
161 for (int i = static_cast<int>(parts_list_.size())-1; i >= 0; --i)
162 delete parts_list_[i];
163 parts_list_.clear();
164
180 #if defined(OS_WIN) 165 #if defined(OS_WIN)
181 OleUninitialize(); 166 OleUninitialize();
182 #endif 167 #endif
183 } 168 }
184 169
185 void BrowserMainParts::EarlyInitialization() { 170 void BrowserMainLoop::Init() {
186 PreEarlyInitialization(); 171 GetContentClient()->browser()->CreateBrowserMainParts(
172 parameters_, &parts_list_);
173 }
174
175 // BrowserMainLoop stages ==================================================
176
177 void BrowserMainLoop::EarlyInitialization() {
178 for (size_t i = 0; i < parts_list_.size(); ++i)
179 parts_list_[i]->PreEarlyInitialization();
180
181 // Start watching for jank during shutdown. It gets disarmed when
187 182
188 #if defined(OS_WIN) 183 #if defined(OS_WIN)
189 net::EnsureWinsockInit(); 184 net::EnsureWinsockInit();
190 #endif 185 #endif
191 186
192 // Use NSS for SSL by default. 187 // Use NSS for SSL by default.
193 // The default client socket factory uses NSS for SSL by default on 188 // The default client socket factory uses NSS for SSL by default on
194 // Windows and Mac. 189 // Windows and Mac.
190 bool init_nspr = false;
195 #if defined(OS_WIN) || defined(OS_MACOSX) 191 #if defined(OS_WIN) || defined(OS_MACOSX)
196 if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) { 192 if (parsed_command_line_.HasSwitch(switches::kUseSystemSSL)) {
197 net::ClientSocketFactory::UseSystemSSL(); 193 net::ClientSocketFactory::UseSystemSSL();
198 } else { 194 } else {
195 init_nspr = true;
196 }
199 #elif defined(USE_NSS) 197 #elif defined(USE_NSS)
200 if (true) { 198 init_nspr = true;
201 #else
202 if (false) {
203 #endif 199 #endif
200 if (init_nspr) {
204 // We want to be sure to init NSPR on the main thread. 201 // We want to be sure to init NSPR on the main thread.
205 crypto::EnsureNSPRInit(); 202 crypto::EnsureNSPRInit();
206 } 203 }
207 204
208 #if defined(OS_POSIX) && !defined(OS_MACOSX) 205 #if defined(OS_POSIX) && !defined(OS_MACOSX)
209 SetupSandbox(parsed_command_line()); 206 SetupSandbox(parsed_command_line_);
210 #endif 207 #endif
211 208
212 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart)) 209 if (parsed_command_line_.HasSwitch(switches::kDisableSSLFalseStart))
213 net::SSLConfigService::DisableFalseStart(); 210 net::SSLConfigService::DisableFalseStart();
214 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo)) 211 if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo))
215 net::SSLConfigService::EnableCachedInfo(); 212 net::SSLConfigService::EnableCachedInfo();
216 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts)) 213 if (parsed_command_line_.HasSwitch(switches::kEnableOriginBoundCerts))
217 net::SSLConfigService::EnableOriginBoundCerts(); 214 net::SSLConfigService::EnableOriginBoundCerts();
218 if (parsed_command_line().HasSwitch( 215 if (parsed_command_line_.HasSwitch(
219 switches::kEnableDNSCertProvenanceChecking)) { 216 switches::kEnableDNSCertProvenanceChecking)) {
220 net::SSLConfigService::EnableDNSCertProvenanceChecking(); 217 net::SSLConfigService::EnableDNSCertProvenanceChecking();
221 } 218 }
222 219
223 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't 220 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
224 // seem dependent on SSL initialization(). 221 // seem dependent on SSL initialization().
225 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen)) 222 if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen))
226 net::set_tcp_fastopen_enabled(true); 223 net::set_tcp_fastopen_enabled(true);
227 224
228 PostEarlyInitialization(); 225 for (size_t i = 0; i < parts_list_.size(); ++i)
226 parts_list_[i]->PostEarlyInitialization();
229 } 227 }
230 228
231 void BrowserMainParts::MainMessageLoopStart() { 229 void BrowserMainLoop::MainMessageLoopStart() {
232 PreMainMessageLoopStart(); 230 for (size_t i = 0; i < parts_list_.size(); ++i)
231 parts_list_[i]->PreMainMessageLoopStart();
233 232
234 #if defined(OS_WIN) 233 #if defined(OS_WIN)
235 // If we're running tests (ui_task is non-null), then the ResourceBundle 234 // If we're running tests (ui_task is non-null), then the ResourceBundle
236 // has already been initialized. 235 // has already been initialized.
237 if (!parameters().ui_task) { 236 if (!parameters_.ui_task) {
238 // Override the configured locale with the user's preferred UI language. 237 // Override the configured locale with the user's preferred UI language.
239 l10n_util::OverrideLocaleWithUILanguageList(); 238 l10n_util::OverrideLocaleWithUILanguageList();
240 } 239 }
241 #endif 240 #endif
242 241
243 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); 242 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
244 243
245 InitializeMainThread(); 244 InitializeMainThread();
246 245
247 system_monitor_.reset(new base::SystemMonitor); 246 system_monitor_.reset(new base::SystemMonitor);
248 hi_res_timer_manager_.reset(new HighResolutionTimerManager); 247 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
249 248
250 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); 249 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
251 250
252 PostMainMessageLoopStart(); 251 for (size_t i = 0; i < parts_list_.size(); ++i)
252 parts_list_[i]->PostMainMessageLoopStart();
253 } 253 }
254 254
255 static bool g_exited_main_message_loop = false; 255 void BrowserMainLoop::RunMainMessageLoopParts(
256 256 bool* completed_main_message_loop) {
257 void BrowserMainParts::RunMainMessageLoopParts() { 257 for (size_t i = 0; i < parts_list_.size(); ++i)
258 PreMainMessageLoopRun(); 258 parts_list_[i]->PreMainMessageLoopRun();
259 259
260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
261 // If the UI thread blocks, the whole UI is unresponsive. 261 // If the UI thread blocks, the whole UI is unresponsive.
262 // Do not allow disk IO from the UI thread. 262 // Do not allow disk IO from the UI thread.
263 base::ThreadRestrictions::SetIOAllowed(false); 263 base::ThreadRestrictions::SetIOAllowed(false);
264 MainMessageLoopRun(); 264
265 // Iterate through each of the parts. If any of them ran the main
266 // message loop then they should return |true|. Otherwise
267 // BrowserMainLoop::MainMessageLoopRun loop will be run.
268 bool ran_main_loop = false;
269 for (size_t i = 0; i < parts_list_.size(); ++i) {
270 int result_code = result_code_;
271 if (parts_list_[i]->MainMessageLoopRun(&result_code)) {
272 ran_main_loop = true;
273 result_code_ = result_code;
274 }
275 }
276 if (!ran_main_loop)
277 MainMessageLoopRun();
278
265 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 279 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
266 280
267 g_exited_main_message_loop = true; 281 if (completed_main_message_loop)
282 *completed_main_message_loop = true;
268 283
269 PostMainMessageLoopRun(); 284 for (size_t i = 0; i < parts_list_.size(); ++i)
285 parts_list_[i]->PostMainMessageLoopRun();
270 } 286 }
271 287
272 void BrowserMainParts::InitializeMainThread() { 288 void BrowserMainLoop::InitializeMainThread() {
273 const char* kThreadName = "CrBrowserMain"; 289 const char* kThreadName = "CrBrowserMain";
274 base::PlatformThread::SetName(kThreadName); 290 base::PlatformThread::SetName(kThreadName);
275 main_message_loop().set_thread_name(kThreadName); 291 main_message_loop_->set_thread_name(kThreadName);
276 292
277 #if defined(TRACK_ALL_TASK_OBJECTS) 293 #if defined(TRACK_ALL_TASK_OBJECTS)
278 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); 294 tracked_objects::ThreadData::InitializeThreadContext(kThreadName);
279 #endif // TRACK_ALL_TASK_OBJECTS 295 #endif // TRACK_ALL_TASK_OBJECTS
280 296
281 // Register the main thread by instantiating it, but don't call any methods. 297 // Register the main thread by instantiating it, but don't call any methods.
282 main_thread_.reset(new BrowserThread(BrowserThread::UI, 298 main_thread_.reset(new BrowserThread(BrowserThread::UI,
283 MessageLoop::current())); 299 MessageLoop::current()));
284 } 300 }
285 301
286 void BrowserMainParts::InitializeToolkit() { 302 void BrowserMainLoop::InitializeToolkit() {
287 // TODO(evan): this function is rather subtle, due to the variety 303 // TODO(evan): this function is rather subtle, due to the variety
288 // of intersecting ifdefs we have. To keep it easy to follow, there 304 // of intersecting ifdefs we have. To keep it easy to follow, there
289 // are no #else branches on any #ifs. 305 // are no #else branches on any #ifs.
290 306 // TODO(stevenjb): Move platform specific code into platform specific Parts
307 // (Need to add InitializeToolkit stage to BrowserParts).
291 #if defined(OS_LINUX) 308 #if defined(OS_LINUX)
292 // We want to call g_thread_init(), but in some codepaths (tests) it 309 // We want to call g_thread_init(), but in some codepaths (tests) it
293 // is possible it has already been called. In older versions of 310 // is possible it has already been called. In older versions of
294 // GTK, it is an error to call g_thread_init twice; unfortunately, 311 // GTK, it is an error to call g_thread_init twice; unfortunately,
295 // the API to tell whether it has been called already was also only 312 // the API to tell whether it has been called already was also only
296 // added in a newer version of GTK! Thankfully, this non-intuitive 313 // added in a newer version of GTK! Thankfully, this non-intuitive
297 // check is actually equivalent and sufficient to work around the 314 // check is actually equivalent and sufficient to work around the
298 // error. 315 // error.
299 if (!g_thread_supported()) 316 if (!g_thread_supported())
300 g_thread_init(NULL); 317 g_thread_init(NULL);
301 // Glib type system initialization. Needed at least for gconf, 318 // Glib type system initialization. Needed at least for gconf,
302 // used in net/proxy/proxy_config_service_linux.cc. Most likely 319 // used in net/proxy/proxy_config_service_linux.cc. Most likely
303 // this is superfluous as gtk_init() ought to do this. It's 320 // this is superfluous as gtk_init() ought to do this. It's
304 // definitely harmless, so retained as a reminder of this 321 // definitely harmless, so retained as a reminder of this
305 // requirement for gconf. 322 // requirement for gconf.
306 g_type_init(); 323 g_type_init();
324
307 #if defined(OS_CHROMEOS) 325 #if defined(OS_CHROMEOS)
308 // ChromeOS still uses dbus-glib, so initialize its threading here. 326 // ChromeOS still uses dbus-glib, so initialize its threading here.
309 // TODO(satorux, stevenjb): remove this once it is no longer needed. 327 // TODO(satorux, stevenjb): remove this once it is no longer needed.
310 dbus_g_thread_init(); 328 dbus_g_thread_init();
311 #endif 329 #endif
330
312 #if !defined(USE_AURA) 331 #if !defined(USE_AURA)
313 gfx::GtkInitFromCommandLine(parameters().command_line_); 332 gfx::GtkInitFromCommandLine(parameters_.command_line_);
314 #endif 333 #endif
334
315 SetUpGLibLogHandler(); 335 SetUpGLibLogHandler();
316 #endif 336 #endif
317 337
318 #if defined(TOOLKIT_GTK) 338 #if defined(TOOLKIT_GTK)
319 // It is important for this to happen before the first run dialog, as it 339 // It is important for this to happen before the first run dialog, as it
320 // styles the dialog as well. 340 // styles the dialog as well.
321 gfx::InitRCStyles(); 341 gfx::InitRCStyles();
322 #endif 342 #endif
323 343
324 #if defined(OS_WIN) 344 #if defined(OS_WIN)
325 // Init common control sex. 345 // Init common control sex.
326 INITCOMMONCONTROLSEX config; 346 INITCOMMONCONTROLSEX config;
327 config.dwSize = sizeof(config); 347 config.dwSize = sizeof(config);
328 config.dwICC = ICC_WIN95_CLASSES; 348 config.dwICC = ICC_WIN95_CLASSES;
329 if (!InitCommonControlsEx(&config)) 349 if (!InitCommonControlsEx(&config))
330 LOG_GETLASTERROR(FATAL); 350 LOG_GETLASTERROR(FATAL);
331 #endif 351 #endif
332 352
333 ToolkitInitialized(); 353 for (size_t i = 0; i < parts_list_.size(); ++i)
354 parts_list_[i]->ToolkitInitialized();
334 } 355 }
335 356
336 void BrowserMainParts::PreEarlyInitialization() { 357 void BrowserMainLoop::MainMessageLoopRun() {
337 } 358 if (parameters_.ui_task)
338 359 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task);
339 void BrowserMainParts::PostEarlyInitialization() {
340 }
341
342 void BrowserMainParts::PreMainMessageLoopStart() {
343 }
344
345 void BrowserMainParts::PostMainMessageLoopStart() {
346 }
347
348 void BrowserMainParts::PreMainMessageLoopRun() {
349 }
350
351 void BrowserMainParts::MainMessageLoopRun() {
352 if (parameters().ui_task)
353 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters().ui_task);
354 360
355 #if defined(OS_MACOSX) 361 #if defined(OS_MACOSX)
356 MessageLoopForUI::current()->Run(); 362 MessageLoopForUI::current()->Run();
357 #else 363 #else
358 MessageLoopForUI::current()->RunWithDispatcher(NULL); 364 MessageLoopForUI::current()->RunWithDispatcher(NULL);
359 #endif 365 #endif
360 } 366 }
361 367
362 void BrowserMainParts::PostMainMessageLoopRun() {
363 }
364
365 void BrowserMainParts::ToolkitInitialized() {
366 }
367
368 bool ExitedMainMessageLoop() {
369 return g_exited_main_message_loop;
370 }
371
372 } // namespace content 368 } // namespace content
373
374 // Main routine for running as the Browser process.
375 int BrowserMain(const MainFunctionParams& parameters) {
376 TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, "");
377
378 NotificationServiceImpl main_notification_service;
379
380 scoped_ptr<content::BrowserMainParts> parts(
381 content::GetContentClient()->browser()->CreateBrowserMainParts(
382 parameters));
383 if (!parts.get())
384 parts.reset(new content::BrowserMainParts(parameters));
385
386 parts->EarlyInitialization();
387
388 // Must happen before we try to use a message loop or display any UI.
389 parts->InitializeToolkit();
390
391 parts->MainMessageLoopStart();
392
393 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here
394 // are NOT deleted. If you need something to run during WM_ENDSESSION add it
395 // to browser_shutdown::Shutdown or BrowserProcess::EndSession.
396
397 // !!!!!!!!!! READ ME !!!!!!!!!!
398 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you
399 // need to add something above this comment, read the documentation in
400 // browser_main.h. If you need to add something below, please do the
401 // following:
402 // - Figure out where you should add your code. Do NOT just pick a random
403 // location "which works".
404 // - Document the dependencies apart from compile-time-checkable ones. What
405 // must happen before your new code is executed? Does your new code need to
406 // run before something else? Are there performance reasons for executing
407 // your code at that point?
408 // - If you need to create a (persistent) object, heap allocate it and keep a
409 // |scoped_ptr| to it rather than allocating it on the stack. Otherwise
410 // I'll have to convert your code when I refactor.
411 // - Unless your new code is just a couple of lines, factor it out into a
412 // function with a well-defined purpose. Do NOT just add it inline in
413 // |BrowserMain()|.
414 // Thanks!
415
416 // TODO(viettrungluu): put the remainder into BrowserMainParts
417
418 #if defined(OS_WIN)
419 #if !defined(NO_TCMALLOC)
420 // When linking shared libraries, NO_TCMALLOC is defined, and dynamic
421 // allocator selection is not supported.
422
423 // Make this call before going multithreaded, or spawning any subprocesses.
424 base::allocator::SetupSubprocessAllocator();
425 #endif
426 // The broker service initialization needs to run early because it will
427 // initialize the sandbox broker, which requires the process to swap its
428 // window station. During this time all the UI will be broken. This has to
429 // run before threads and windows are created.
430 InitializeBrokerServices(parameters, parameters.command_line_);
431
432 base::win::ScopedCOMInitializer com_initializer;
433 #endif // OS_WIN
434
435 base::StatisticsRecorder statistics;
436
437 parts->RunMainMessageLoopParts();
438
439 TRACE_EVENT_END_ETW("BrowserMain", 0, 0);
440 return parts->result_code();
441 }
OLDNEW
« no previous file with comments | « content/browser/browser_main_loop.h ('k') | content/browser/mock_content_browser_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698