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

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

Powered by Google App Engine
This is Rietveld 408576698