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

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

Issue 19957002: Run the later parts of startup as UI thread tasks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Run the later parts of startup as UI thread tasks - one more Mac fix Created 7 years, 4 months 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
OLDNEW
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/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/pending_task.h" 14 #include "base/pending_task.h"
15 #include "base/power_monitor/power_monitor.h" 15 #include "base/power_monitor/power_monitor.h"
16 #include "base/process/process_metrics.h" 16 #include "base/process/process_metrics.h"
17 #include "base/run_loop.h" 17 #include "base/run_loop.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/system_monitor/system_monitor.h" 19 #include "base/system_monitor/system_monitor.h"
20 #include "base/threading/thread_restrictions.h" 20 #include "base/threading/thread_restrictions.h"
21 #include "base/timer/hi_res_timer_manager.h" 21 #include "base/timer/hi_res_timer_manager.h"
22 #include "content/browser/browser_startup_configuration.h"
22 #include "content/browser/browser_thread_impl.h" 23 #include "content/browser/browser_thread_impl.h"
23 #include "content/browser/device_orientation/device_motion_service.h" 24 #include "content/browser/device_orientation/device_motion_service.h"
24 #include "content/browser/download/save_file_manager.h" 25 #include "content/browser/download/save_file_manager.h"
25 #include "content/browser/gamepad/gamepad_service.h" 26 #include "content/browser/gamepad/gamepad_service.h"
26 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" 27 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
27 #include "content/browser/gpu/gpu_data_manager_impl.h" 28 #include "content/browser/gpu/gpu_data_manager_impl.h"
28 #include "content/browser/gpu/gpu_process_host.h" 29 #include "content/browser/gpu/gpu_process_host.h"
29 #include "content/browser/gpu/gpu_process_host_ui_shim.h" 30 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
30 #include "content/browser/histogram_synchronizer.h" 31 #include "content/browser/histogram_synchronizer.h"
31 #include "content/browser/loader/resource_dispatcher_host_impl.h" 32 #include "content/browser/loader/resource_dispatcher_host_impl.h"
32 #include "content/browser/net/browser_online_state_observer.h" 33 #include "content/browser/net/browser_online_state_observer.h"
33 #include "content/browser/plugin_service_impl.h" 34 #include "content/browser/plugin_service_impl.h"
34 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" 35 #include "content/browser/renderer_host/media/audio_mirroring_manager.h"
35 #include "content/browser/renderer_host/media/media_stream_manager.h" 36 #include "content/browser/renderer_host/media/media_stream_manager.h"
36 #include "content/browser/speech/speech_recognition_manager_impl.h" 37 #include "content/browser/speech/speech_recognition_manager_impl.h"
38 #include "content/browser/startup_task_runner.h"
37 #include "content/browser/tracing/trace_controller_impl.h" 39 #include "content/browser/tracing/trace_controller_impl.h"
38 #include "content/browser/webui/content_web_ui_controller_factory.h" 40 #include "content/browser/webui/content_web_ui_controller_factory.h"
39 #include "content/browser/webui/url_data_manager.h" 41 #include "content/browser/webui/url_data_manager.h"
40 #include "content/public/browser/browser_main_parts.h" 42 #include "content/public/browser/browser_main_parts.h"
41 #include "content/public/browser/browser_shutdown.h" 43 #include "content/public/browser/browser_shutdown.h"
42 #include "content/public/browser/compositor_util.h" 44 #include "content/public/browser/compositor_util.h"
43 #include "content/public/browser/content_browser_client.h" 45 #include "content/public/browser/content_browser_client.h"
44 #include "content/public/browser/render_process_host.h" 46 #include "content/public/browser/render_process_host.h"
45 #include "content/public/common/content_switches.h" 47 #include "content/public/common/content_switches.h"
46 #include "content/public/common/main_function_params.h" 48 #include "content/public/common/main_function_params.h"
47 #include "content/public/common/result_codes.h" 49 #include "content/public/common/result_codes.h"
50 #include "content/browser/startup_task_runner.h"
48 #include "crypto/nss_util.h" 51 #include "crypto/nss_util.h"
49 #include "media/audio/audio_manager.h" 52 #include "media/audio/audio_manager.h"
50 #include "media/base/media.h" 53 #include "media/base/media.h"
51 #include "media/midi/midi_manager.h" 54 #include "media/midi/midi_manager.h"
52 #include "net/base/network_change_notifier.h" 55 #include "net/base/network_change_notifier.h"
53 #include "net/socket/client_socket_factory.h" 56 #include "net/socket/client_socket_factory.h"
54 #include "net/ssl/ssl_config_service.h" 57 #include "net/ssl/ssl_config_service.h"
55 #include "ui/base/clipboard/clipboard.h" 58 #include "ui/base/clipboard/clipboard.h"
56 59
57 #if defined(USE_AURA) 60 #if defined(USE_AURA)
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 // BrowserMainLoop construction / destruction ============================= 295 // BrowserMainLoop construction / destruction =============================
293 296
294 BrowserMainLoop* BrowserMainLoop::GetInstance() { 297 BrowserMainLoop* BrowserMainLoop::GetInstance() {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296 return g_current_browser_main_loop; 299 return g_current_browser_main_loop;
297 } 300 }
298 301
299 BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters) 302 BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
300 : parameters_(parameters), 303 : parameters_(parameters),
301 parsed_command_line_(parameters.command_line), 304 parsed_command_line_(parameters.command_line),
302 result_code_(RESULT_CODE_NORMAL_EXIT) { 305 result_code_(RESULT_CODE_NORMAL_EXIT),
306 created_threads_(false) {
303 DCHECK(!g_current_browser_main_loop); 307 DCHECK(!g_current_browser_main_loop);
304 g_current_browser_main_loop = this; 308 g_current_browser_main_loop = this;
305 } 309 }
306 310
307 BrowserMainLoop::~BrowserMainLoop() { 311 BrowserMainLoop::~BrowserMainLoop() {
308 DCHECK_EQ(this, g_current_browser_main_loop); 312 DCHECK_EQ(this, g_current_browser_main_loop);
309 #if !defined(OS_IOS) 313 #if !defined(OS_IOS)
310 ui::Clipboard::DestroyClipboardForCurrentThread(); 314 ui::Clipboard::DestroyClipboardForCurrentThread();
311 #endif // !defined(OS_IOS) 315 #endif // !defined(OS_IOS)
312 g_current_browser_main_loop = NULL; 316 g_current_browser_main_loop = NULL;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 480
477 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) 481 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
478 trace_memory_controller_.reset(new base::debug::TraceMemoryController( 482 trace_memory_controller_.reset(new base::debug::TraceMemoryController(
479 base::MessageLoop::current()->message_loop_proxy(), 483 base::MessageLoop::current()->message_loop_proxy(),
480 ::HeapProfilerWithPseudoStackStart, 484 ::HeapProfilerWithPseudoStackStart,
481 ::HeapProfilerStop, 485 ::HeapProfilerStop,
482 ::GetHeapProfile)); 486 ::GetHeapProfile));
483 #endif 487 #endif
484 } 488 }
485 489
486 void BrowserMainLoop::CreateThreads() { 490 int BrowserMainLoop::PreCreateThreads() {
487 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads")
488 491
489 if (parts_) { 492 if (parts_) {
490 TRACE_EVENT0("startup", 493 TRACE_EVENT0("startup",
491 "BrowserMainLoop::CreateThreads:PreCreateThreads"); 494 "BrowserMainLoop::CreateThreads:PreCreateThreads");
492 result_code_ = parts_->PreCreateThreads(); 495 result_code_ = parts_->PreCreateThreads();
493 } 496 }
494 497
495 #if defined(ENABLE_PLUGINS) 498 #if defined(ENABLE_PLUGINS)
496 // Prior to any processing happening on the io thread, we create the 499 // Prior to any processing happening on the io thread, we create the
497 // plugin service as it is predominantly used from the io thread, 500 // plugin service as it is predominantly used from the io thread,
498 // but must be created on the main thread. The service ctor is 501 // but must be created on the main thread. The service ctor is
499 // inexpensive and does not invoke the io_thread() accessor. 502 // inexpensive and does not invoke the io_thread() accessor.
500 { 503 {
501 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService") 504 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService")
502 PluginService::GetInstance()->Init(); 505 PluginService::GetInstance()->Init();
503 } 506 }
504 #endif 507 #endif
505 508
506 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID)) 509 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID))
507 // Single-process is an unsupported and not fully tested mode, so 510 // Single-process is an unsupported and not fully tested mode, so
508 // don't enable it for official Chrome builds (except on Android). 511 // don't enable it for official Chrome builds (except on Android).
509 if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) 512 if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
510 RenderProcessHost::SetRunRendererInProcess(true); 513 RenderProcessHost::SetRunRendererInProcess(true);
511 #endif 514 #endif
515 return result_code_;
516 }
512 517
513 if (result_code_ > 0) 518 void BrowserMainLoop::CreateStartupTasks() {
514 return; 519 TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks")
520
521 scoped_refptr<StartupTaskRunner> task_runner =
522 new StartupTaskRunner(BrowserMayStartAsynchronously(),
523 BrowserStartupComplete,
524 base::MessageLoop::current()->message_loop_proxy());
525
526 StartupTask pre_create_threads =
527 base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
528 task_runner->AddTask(pre_create_threads);
529
530 StartupTask create_threads =
531 base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this));
532 task_runner->AddTask(create_threads);
533
534 StartupTask browser_thread_started = base::Bind(
535 &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
536 task_runner->AddTask(browser_thread_started);
537
538 StartupTask pre_main_message_loop_run = base::Bind(
539 &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
540 task_runner->AddTask(pre_main_message_loop_run);
541
542 task_runner->StartRunningTasks();
543 }
544
545 int BrowserMainLoop::CreateThreads() {
546 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads");
515 547
516 base::Thread::Options default_options; 548 base::Thread::Options default_options;
517 base::Thread::Options io_message_loop_options; 549 base::Thread::Options io_message_loop_options;
518 io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO; 550 io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
519 base::Thread::Options ui_message_loop_options; 551 base::Thread::Options ui_message_loop_options;
520 ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI; 552 ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI;
521 553
522 // Start threads in the order they occur in the BrowserThread::ID 554 // Start threads in the order they occur in the BrowserThread::ID
523 // enumeration, except for BrowserThread::UI which is the main 555 // enumeration, except for BrowserThread::UI which is the main
524 // thread. 556 // thread.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 if (thread_to_start) { 621 if (thread_to_start) {
590 (*thread_to_start).reset(new BrowserProcessSubThread(id)); 622 (*thread_to_start).reset(new BrowserProcessSubThread(id));
591 (*thread_to_start)->StartWithOptions(*options); 623 (*thread_to_start)->StartWithOptions(*options);
592 } else { 624 } else {
593 NOTREACHED(); 625 NOTREACHED();
594 } 626 }
595 627
596 TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start"); 628 TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start");
597 629
598 } 630 }
631 created_threads_ = true;
632 return result_code_;
633 }
599 634
600 #if !defined(OS_IOS) 635 int BrowserMainLoop::PreMainMessageLoopRun() {
601 indexed_db_thread_.reset(new base::Thread("IndexedDB"));
602 indexed_db_thread_->Start();
603 #endif
604
605 BrowserThreadsStarted();
606
607 if (parts_) { 636 if (parts_) {
608 TRACE_EVENT0("startup", 637 TRACE_EVENT0("startup",
609 "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun"); 638 "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
610 parts_->PreMainMessageLoopRun(); 639 parts_->PreMainMessageLoopRun();
611 } 640 }
612 641
613 // If the UI thread blocks, the whole UI is unresponsive. 642 // If the UI thread blocks, the whole UI is unresponsive.
614 // Do not allow disk IO from the UI thread. 643 // Do not allow disk IO from the UI thread.
615 base::ThreadRestrictions::SetIOAllowed(false); 644 base::ThreadRestrictions::SetIOAllowed(false);
616 base::ThreadRestrictions::DisallowWaiting(); 645 base::ThreadRestrictions::DisallowWaiting();
646 return result_code_;
617 } 647 }
618 648
619 void BrowserMainLoop::RunMainMessageLoopParts() { 649 void BrowserMainLoop::RunMainMessageLoopParts() {
620 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 650 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
621 651
622 bool ran_main_loop = false; 652 bool ran_main_loop = false;
623 if (parts_) 653 if (parts_)
624 ran_main_loop = parts_->MainMessageLoopRun(&result_code_); 654 ran_main_loop = parts_->MainMessageLoopRun(&result_code_);
625 655
626 if (!ran_main_loop) 656 if (!ran_main_loop)
627 MainMessageLoopRun(); 657 MainMessageLoopRun();
628 658
629 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 659 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
630 } 660 }
631 661
632 void BrowserMainLoop::ShutdownThreadsAndCleanUp() { 662 void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
663
664 if (!created_threads_) {
665 // Called early, nothing to do
666 return;
667 }
633 // Teardown may start in PostMainMessageLoopRun, and during teardown we 668 // Teardown may start in PostMainMessageLoopRun, and during teardown we
634 // need to be able to perform IO. 669 // need to be able to perform IO.
635 base::ThreadRestrictions::SetIOAllowed(true); 670 base::ThreadRestrictions::SetIOAllowed(true);
636 BrowserThread::PostTask( 671 BrowserThread::PostTask(
637 BrowserThread::IO, FROM_HERE, 672 BrowserThread::IO, FROM_HERE,
638 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 673 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
639 true)); 674 true));
640 675
641 if (parts_) 676 if (parts_)
642 parts_->PostMainMessageLoopRun(); 677 parts_->PostMainMessageLoopRun();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 const char* kThreadName = "CrBrowserMain"; 793 const char* kThreadName = "CrBrowserMain";
759 base::PlatformThread::SetName(kThreadName); 794 base::PlatformThread::SetName(kThreadName);
760 if (main_message_loop_) 795 if (main_message_loop_)
761 main_message_loop_->set_thread_name(kThreadName); 796 main_message_loop_->set_thread_name(kThreadName);
762 797
763 // Register the main thread by instantiating it, but don't call any methods. 798 // Register the main thread by instantiating it, but don't call any methods.
764 main_thread_.reset( 799 main_thread_.reset(
765 new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current())); 800 new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current()));
766 } 801 }
767 802
768 void BrowserMainLoop::BrowserThreadsStarted() { 803 int BrowserMainLoop::BrowserThreadsStarted() {
769 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted") 804 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted")
805
806 #if !defined(OS_IOS)
807 indexed_db_thread_.reset(new base::Thread("IndexedDB"));
808 indexed_db_thread_->Start();
809 #endif
810
770 #if defined(OS_ANDROID) 811 #if defined(OS_ANDROID)
771 // Up the priority of anything that touches with display tasks 812 // Up the priority of anything that touches with display tasks
772 // (this thread is UI thread, and io_thread_ is for IPCs). 813 // (this thread is UI thread, and io_thread_ is for IPCs).
773 io_thread_->SetPriority(base::kThreadPriority_Display); 814 io_thread_->SetPriority(base::kThreadPriority_Display);
774 base::PlatformThread::SetThreadPriority( 815 base::PlatformThread::SetThreadPriority(
775 base::PlatformThread::CurrentHandle(), 816 base::PlatformThread::CurrentHandle(),
776 base::kThreadPriority_Display); 817 base::kThreadPriority_Display);
777 #endif 818 #endif
778 819
779 #if !defined(OS_IOS) 820 #if !defined(OS_IOS)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 !parsed_command_line_.HasSwitch(switches::kInProcessGPU)) { 878 !parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
838 TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process", 879 TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
839 TRACE_EVENT_SCOPE_THREAD); 880 TRACE_EVENT_SCOPE_THREAD);
840 BrowserThread::PostTask( 881 BrowserThread::PostTask(
841 BrowserThread::IO, FROM_HERE, base::Bind( 882 BrowserThread::IO, FROM_HERE, base::Bind(
842 base::IgnoreResult(&GpuProcessHost::Get), 883 base::IgnoreResult(&GpuProcessHost::Get),
843 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 884 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
844 CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP)); 885 CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP));
845 } 886 }
846 #endif // !defined(OS_IOS) 887 #endif // !defined(OS_IOS)
888 return result_code_;
847 } 889 }
848 890
849 void BrowserMainLoop::InitializeToolkit() { 891 void BrowserMainLoop::InitializeToolkit() {
850 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit") 892 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit")
851 // TODO(evan): this function is rather subtle, due to the variety 893 // TODO(evan): this function is rather subtle, due to the variety
852 // of intersecting ifdefs we have. To keep it easy to follow, there 894 // of intersecting ifdefs we have. To keep it easy to follow, there
853 // are no #else branches on any #ifs. 895 // are no #else branches on any #ifs.
854 // TODO(stevenjb): Move platform specific code into platform specific Parts 896 // TODO(stevenjb): Move platform specific code into platform specific Parts
855 // (Need to add InitializeToolkit stage to BrowserParts). 897 // (Need to add InitializeToolkit stage to BrowserParts).
856 #if defined(OS_LINUX) || defined(OS_OPENBSD) 898 #if defined(OS_LINUX) || defined(OS_OPENBSD)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 if (parameters_.ui_task) 943 if (parameters_.ui_task)
902 base::MessageLoopForUI::current()->PostTask(FROM_HERE, 944 base::MessageLoopForUI::current()->PostTask(FROM_HERE,
903 *parameters_.ui_task); 945 *parameters_.ui_task);
904 946
905 base::RunLoop run_loop; 947 base::RunLoop run_loop;
906 run_loop.Run(); 948 run_loop.Run();
907 #endif 949 #endif
908 } 950 }
909 951
910 } // namespace content 952 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698