| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_loop.h" | 5 #include "content/browser/browser_main_loop.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/hi_res_timer_manager.h" | 10 #include "base/hi_res_timer_manager.h" |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 void BrowserMainLoop::EarlyInitialization() { | 302 void BrowserMainLoop::EarlyInitialization() { |
| 303 #if defined(USE_X11) | 303 #if defined(USE_X11) |
| 304 if (parsed_command_line_.HasSwitch(switches::kSingleProcess) || | 304 if (parsed_command_line_.HasSwitch(switches::kSingleProcess) || |
| 305 parsed_command_line_.HasSwitch(switches::kInProcessGPU)) { | 305 parsed_command_line_.HasSwitch(switches::kInProcessGPU)) { |
| 306 if (!XInitThreads()) { | 306 if (!XInitThreads()) { |
| 307 LOG(ERROR) << "Failed to put Xlib into threaded mode."; | 307 LOG(ERROR) << "Failed to put Xlib into threaded mode."; |
| 308 } | 308 } |
| 309 } | 309 } |
| 310 #endif | 310 #endif |
| 311 | 311 |
| 312 if (parts_.get()) | 312 if (parts_) |
| 313 parts_->PreEarlyInitialization(); | 313 parts_->PreEarlyInitialization(); |
| 314 | 314 |
| 315 #if defined(OS_WIN) | 315 #if defined(OS_WIN) |
| 316 net::EnsureWinsockInit(); | 316 net::EnsureWinsockInit(); |
| 317 #endif | 317 #endif |
| 318 | 318 |
| 319 #if !defined(USE_OPENSSL) | 319 #if !defined(USE_OPENSSL) |
| 320 // We want to be sure to init NSPR on the main thread. | 320 // We want to be sure to init NSPR on the main thread. |
| 321 crypto::EnsureNSPRInit(); | 321 crypto::EnsureNSPRInit(); |
| 322 #endif // !defined(USE_OPENSSL) | 322 #endif // !defined(USE_OPENSSL) |
| 323 | 323 |
| 324 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 324 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 325 SetupSandbox(parsed_command_line_); | 325 SetupSandbox(parsed_command_line_); |
| 326 #endif | 326 #endif |
| 327 | 327 |
| 328 if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo)) | 328 if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo)) |
| 329 net::SSLConfigService::EnableCachedInfo(); | 329 net::SSLConfigService::EnableCachedInfo(); |
| 330 | 330 |
| 331 #if !defined(OS_IOS) | 331 #if !defined(OS_IOS) |
| 332 if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) { | 332 if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) { |
| 333 std::string limit_string = parsed_command_line_.GetSwitchValueASCII( | 333 std::string limit_string = parsed_command_line_.GetSwitchValueASCII( |
| 334 switches::kRendererProcessLimit); | 334 switches::kRendererProcessLimit); |
| 335 size_t process_limit; | 335 size_t process_limit; |
| 336 if (base::StringToSizeT(limit_string, &process_limit)) { | 336 if (base::StringToSizeT(limit_string, &process_limit)) { |
| 337 RenderProcessHost::SetMaxRendererProcessCount(process_limit); | 337 RenderProcessHost::SetMaxRendererProcessCount(process_limit); |
| 338 } | 338 } |
| 339 } | 339 } |
| 340 #endif // !defined(OS_IOS) | 340 #endif // !defined(OS_IOS) |
| 341 | 341 |
| 342 if (parts_.get()) | 342 if (parts_) |
| 343 parts_->PostEarlyInitialization(); | 343 parts_->PostEarlyInitialization(); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void BrowserMainLoop::MainMessageLoopStart() { | 346 void BrowserMainLoop::MainMessageLoopStart() { |
| 347 if (parts_.get()) | 347 if (parts_) |
| 348 parts_->PreMainMessageLoopStart(); | 348 parts_->PreMainMessageLoopStart(); |
| 349 | 349 |
| 350 #if defined(OS_WIN) | 350 #if defined(OS_WIN) |
| 351 // If we're running tests (ui_task is non-null), then the ResourceBundle | 351 // If we're running tests (ui_task is non-null), then the ResourceBundle |
| 352 // has already been initialized. | 352 // has already been initialized. |
| 353 if (!parameters_.ui_task) { | 353 if (!parameters_.ui_task) { |
| 354 // Override the configured locale with the user's preferred UI language. | 354 // Override the configured locale with the user's preferred UI language. |
| 355 l10n_util::OverrideLocaleWithUILanguageList(); | 355 l10n_util::OverrideLocaleWithUILanguageList(); |
| 356 } | 356 } |
| 357 #endif | 357 #endif |
| (...skipping 30 matching lines...) Expand all Loading... |
| 388 // plugin service as it is predominantly used from the io thread, | 388 // plugin service as it is predominantly used from the io thread, |
| 389 // but must be created on the main thread. The service ctor is | 389 // but must be created on the main thread. The service ctor is |
| 390 // inexpensive and does not invoke the io_thread() accessor. | 390 // inexpensive and does not invoke the io_thread() accessor. |
| 391 PluginService::GetInstance()->Init(); | 391 PluginService::GetInstance()->Init(); |
| 392 #endif | 392 #endif |
| 393 | 393 |
| 394 #if defined(OS_WIN) | 394 #if defined(OS_WIN) |
| 395 system_message_window_.reset(new SystemMessageWindowWin); | 395 system_message_window_.reset(new SystemMessageWindowWin); |
| 396 #endif | 396 #endif |
| 397 | 397 |
| 398 if (parts_.get()) | 398 if (parts_) |
| 399 parts_->PostMainMessageLoopStart(); | 399 parts_->PostMainMessageLoopStart(); |
| 400 | 400 |
| 401 #if defined(OS_ANDROID) | 401 #if defined(OS_ANDROID) |
| 402 SurfaceTexturePeer::InitInstance(new SurfaceTexturePeerBrowserImpl()); | 402 SurfaceTexturePeer::InitInstance(new SurfaceTexturePeerBrowserImpl()); |
| 403 DataFetcherImplAndroid::Init(base::android::AttachCurrentThread()); | 403 DataFetcherImplAndroid::Init(base::android::AttachCurrentThread()); |
| 404 #endif | 404 #endif |
| 405 | 405 |
| 406 if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) { | 406 if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) { |
| 407 memory_observer_.reset(new MemoryObserver()); | 407 memory_observer_.reset(new MemoryObserver()); |
| 408 MessageLoop::current()->AddTaskObserver(memory_observer_.get()); | 408 MessageLoop::current()->AddTaskObserver(memory_observer_.get()); |
| 409 } | 409 } |
| 410 } | 410 } |
| 411 | 411 |
| 412 void BrowserMainLoop::CreateThreads() { | 412 void BrowserMainLoop::CreateThreads() { |
| 413 if (parts_.get()) | 413 if (parts_) |
| 414 result_code_ = parts_->PreCreateThreads(); | 414 result_code_ = parts_->PreCreateThreads(); |
| 415 | 415 |
| 416 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID)) | 416 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID)) |
| 417 // Single-process is an unsupported and not fully tested mode, so | 417 // Single-process is an unsupported and not fully tested mode, so |
| 418 // don't enable it for official Chrome builds (except on Android). | 418 // don't enable it for official Chrome builds (except on Android). |
| 419 if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) | 419 if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) |
| 420 RenderProcessHost::SetRunRendererInProcess(true); | 420 RenderProcessHost::SetRunRendererInProcess(true); |
| 421 #endif | 421 #endif |
| 422 | 422 |
| 423 if (result_code_ > 0) | 423 if (result_code_ > 0) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 } else if (thread_to_start) { | 490 } else if (thread_to_start) { |
| 491 (*thread_to_start).reset(new BrowserProcessSubThread(id)); | 491 (*thread_to_start).reset(new BrowserProcessSubThread(id)); |
| 492 (*thread_to_start)->StartWithOptions(*options); | 492 (*thread_to_start)->StartWithOptions(*options); |
| 493 } else { | 493 } else { |
| 494 NOTREACHED(); | 494 NOTREACHED(); |
| 495 } | 495 } |
| 496 } | 496 } |
| 497 | 497 |
| 498 BrowserThreadsStarted(); | 498 BrowserThreadsStarted(); |
| 499 | 499 |
| 500 if (parts_.get()) | 500 if (parts_) |
| 501 parts_->PreMainMessageLoopRun(); | 501 parts_->PreMainMessageLoopRun(); |
| 502 | 502 |
| 503 // If the UI thread blocks, the whole UI is unresponsive. | 503 // If the UI thread blocks, the whole UI is unresponsive. |
| 504 // Do not allow disk IO from the UI thread. | 504 // Do not allow disk IO from the UI thread. |
| 505 base::ThreadRestrictions::SetIOAllowed(false); | 505 base::ThreadRestrictions::SetIOAllowed(false); |
| 506 base::ThreadRestrictions::DisallowWaiting(); | 506 base::ThreadRestrictions::DisallowWaiting(); |
| 507 } | 507 } |
| 508 | 508 |
| 509 void BrowserMainLoop::RunMainMessageLoopParts() { | 509 void BrowserMainLoop::RunMainMessageLoopParts() { |
| 510 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 510 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 511 | 511 |
| 512 bool ran_main_loop = false; | 512 bool ran_main_loop = false; |
| 513 if (parts_.get()) | 513 if (parts_) |
| 514 ran_main_loop = parts_->MainMessageLoopRun(&result_code_); | 514 ran_main_loop = parts_->MainMessageLoopRun(&result_code_); |
| 515 | 515 |
| 516 if (!ran_main_loop) | 516 if (!ran_main_loop) |
| 517 MainMessageLoopRun(); | 517 MainMessageLoopRun(); |
| 518 | 518 |
| 519 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 519 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 520 } | 520 } |
| 521 | 521 |
| 522 void BrowserMainLoop::ShutdownThreadsAndCleanUp() { | 522 void BrowserMainLoop::ShutdownThreadsAndCleanUp() { |
| 523 // Teardown may start in PostMainMessageLoopRun, and during teardown we | 523 // Teardown may start in PostMainMessageLoopRun, and during teardown we |
| 524 // need to be able to perform IO. | 524 // need to be able to perform IO. |
| 525 base::ThreadRestrictions::SetIOAllowed(true); | 525 base::ThreadRestrictions::SetIOAllowed(true); |
| 526 BrowserThread::PostTask( | 526 BrowserThread::PostTask( |
| 527 BrowserThread::IO, FROM_HERE, | 527 BrowserThread::IO, FROM_HERE, |
| 528 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), | 528 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), |
| 529 true)); | 529 true)); |
| 530 | 530 |
| 531 if (parts_.get()) | 531 if (parts_) |
| 532 parts_->PostMainMessageLoopRun(); | 532 parts_->PostMainMessageLoopRun(); |
| 533 | 533 |
| 534 #if !defined(OS_IOS) | 534 #if !defined(OS_IOS) |
| 535 // Destroying the GpuProcessHostUIShims on the UI thread posts a task to | 535 // Destroying the GpuProcessHostUIShims on the UI thread posts a task to |
| 536 // delete related objects on the GPU thread. This must be done before | 536 // delete related objects on the GPU thread. This must be done before |
| 537 // stopping the GPU thread. The GPU thread will close IPC channels to renderer | 537 // stopping the GPU thread. The GPU thread will close IPC channels to renderer |
| 538 // processes so this has to happen before stopping the IO thread. | 538 // processes so this has to happen before stopping the IO thread. |
| 539 GpuProcessHostUIShim::DestroyAll(); | 539 GpuProcessHostUIShim::DestroyAll(); |
| 540 | 540 |
| 541 // Cancel pending requests and prevent new requests. | 541 // Cancel pending requests and prevent new requests. |
| 542 if (resource_dispatcher_host_.get()) | 542 if (resource_dispatcher_host_) |
| 543 resource_dispatcher_host_.get()->Shutdown(); | 543 resource_dispatcher_host_.get()->Shutdown(); |
| 544 | 544 |
| 545 #if defined(USE_AURA) | 545 #if defined(USE_AURA) |
| 546 ImageTransportFactory::Terminate(); | 546 ImageTransportFactory::Terminate(); |
| 547 #endif | 547 #endif |
| 548 | 548 |
| 549 // The device monitors are using |system_monitor_| as dependency, so delete | 549 // The device monitors are using |system_monitor_| as dependency, so delete |
| 550 // them before |system_monitor_| goes away. | 550 // them before |system_monitor_| goes away. |
| 551 // On Mac and windows, the monitor needs to be destroyed on the same thread | 551 // On Mac and windows, the monitor needs to be destroyed on the same thread |
| 552 // as they were created. On Linux, the monitor will be deleted when IO thread | 552 // as they were created. On Linux, the monitor will be deleted when IO thread |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 break; | 600 break; |
| 601 case BrowserThread::FILE_USER_BLOCKING: | 601 case BrowserThread::FILE_USER_BLOCKING: |
| 602 thread_to_stop = &file_user_blocking_thread_; | 602 thread_to_stop = &file_user_blocking_thread_; |
| 603 break; | 603 break; |
| 604 case BrowserThread::FILE: | 604 case BrowserThread::FILE: |
| 605 thread_to_stop = &file_thread_; | 605 thread_to_stop = &file_thread_; |
| 606 | 606 |
| 607 #if !defined(OS_IOS) | 607 #if !defined(OS_IOS) |
| 608 // Clean up state that lives on or uses the file_thread_ before | 608 // Clean up state that lives on or uses the file_thread_ before |
| 609 // it goes away. | 609 // it goes away. |
| 610 if (resource_dispatcher_host_.get()) | 610 if (resource_dispatcher_host_) |
| 611 resource_dispatcher_host_.get()->save_file_manager()->Shutdown(); | 611 resource_dispatcher_host_.get()->save_file_manager()->Shutdown(); |
| 612 #endif // !defined(OS_IOS) | 612 #endif // !defined(OS_IOS) |
| 613 break; | 613 break; |
| 614 case BrowserThread::PROCESS_LAUNCHER: | 614 case BrowserThread::PROCESS_LAUNCHER: |
| 615 thread_to_stop = &process_launcher_thread_; | 615 thread_to_stop = &process_launcher_thread_; |
| 616 break; | 616 break; |
| 617 case BrowserThread::CACHE: | 617 case BrowserThread::CACHE: |
| 618 thread_to_stop = &cache_thread_; | 618 thread_to_stop = &cache_thread_; |
| 619 break; | 619 break; |
| 620 case BrowserThread::IO: | 620 case BrowserThread::IO: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 // it. | 653 // it. |
| 654 BrowserGpuChannelHostFactory::Terminate(); | 654 BrowserGpuChannelHostFactory::Terminate(); |
| 655 | 655 |
| 656 // Must happen after the I/O thread is shutdown since this class lives on the | 656 // Must happen after the I/O thread is shutdown since this class lives on the |
| 657 // I/O thread and isn't threadsafe. | 657 // I/O thread and isn't threadsafe. |
| 658 GamepadService::GetInstance()->Terminate(); | 658 GamepadService::GetInstance()->Terminate(); |
| 659 | 659 |
| 660 URLDataManager::DeleteDataSources(); | 660 URLDataManager::DeleteDataSources(); |
| 661 #endif // !defined(OS_IOS) | 661 #endif // !defined(OS_IOS) |
| 662 | 662 |
| 663 if (parts_.get()) | 663 if (parts_) |
| 664 parts_->PostDestroyThreads(); | 664 parts_->PostDestroyThreads(); |
| 665 } | 665 } |
| 666 | 666 |
| 667 void BrowserMainLoop::InitializeMainThread() { | 667 void BrowserMainLoop::InitializeMainThread() { |
| 668 const char* kThreadName = "CrBrowserMain"; | 668 const char* kThreadName = "CrBrowserMain"; |
| 669 base::PlatformThread::SetName(kThreadName); | 669 base::PlatformThread::SetName(kThreadName); |
| 670 if (main_message_loop_.get()) | 670 if (main_message_loop_) |
| 671 main_message_loop_->set_thread_name(kThreadName); | 671 main_message_loop_->set_thread_name(kThreadName); |
| 672 | 672 |
| 673 // Register the main thread by instantiating it, but don't call any methods. | 673 // Register the main thread by instantiating it, but don't call any methods. |
| 674 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, | 674 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
| 675 MessageLoop::current())); | 675 MessageLoop::current())); |
| 676 } | 676 } |
| 677 | 677 |
| 678 #if defined(OS_ANDROID) | 678 #if defined(OS_ANDROID) |
| 679 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) | 679 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) |
| 680 namespace { | 680 namespace { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 | 791 |
| 792 #if defined(OS_WIN) | 792 #if defined(OS_WIN) |
| 793 // Init common control sex. | 793 // Init common control sex. |
| 794 INITCOMMONCONTROLSEX config; | 794 INITCOMMONCONTROLSEX config; |
| 795 config.dwSize = sizeof(config); | 795 config.dwSize = sizeof(config); |
| 796 config.dwICC = ICC_WIN95_CLASSES; | 796 config.dwICC = ICC_WIN95_CLASSES; |
| 797 if (!InitCommonControlsEx(&config)) | 797 if (!InitCommonControlsEx(&config)) |
| 798 LOG_GETLASTERROR(FATAL); | 798 LOG_GETLASTERROR(FATAL); |
| 799 #endif | 799 #endif |
| 800 | 800 |
| 801 if (parts_.get()) | 801 if (parts_) |
| 802 parts_->ToolkitInitialized(); | 802 parts_->ToolkitInitialized(); |
| 803 } | 803 } |
| 804 | 804 |
| 805 void BrowserMainLoop::MainMessageLoopRun() { | 805 void BrowserMainLoop::MainMessageLoopRun() { |
| 806 #if defined(OS_ANDROID) | 806 #if defined(OS_ANDROID) |
| 807 // Android's main message loop is the Java message loop. | 807 // Android's main message loop is the Java message loop. |
| 808 NOTREACHED(); | 808 NOTREACHED(); |
| 809 #else | 809 #else |
| 810 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); | 810 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); |
| 811 if (parameters_.ui_task) | 811 if (parameters_.ui_task) |
| 812 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); | 812 MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task); |
| 813 | 813 |
| 814 base::RunLoop run_loop; | 814 base::RunLoop run_loop; |
| 815 run_loop.Run(); | 815 run_loop.Run(); |
| 816 #endif | 816 #endif |
| 817 } | 817 } |
| 818 | 818 |
| 819 } // namespace content | 819 } // namespace content |
| OLD | NEW |