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

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 - patch for Joth's comments Created 7 years, 5 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"
(...skipping 26 matching lines...) Expand all
37 #include "content/browser/webui/content_web_ui_controller_factory.h" 37 #include "content/browser/webui/content_web_ui_controller_factory.h"
38 #include "content/browser/webui/url_data_manager.h" 38 #include "content/browser/webui/url_data_manager.h"
39 #include "content/public/browser/browser_main_parts.h" 39 #include "content/public/browser/browser_main_parts.h"
40 #include "content/public/browser/browser_shutdown.h" 40 #include "content/public/browser/browser_shutdown.h"
41 #include "content/public/browser/compositor_util.h" 41 #include "content/public/browser/compositor_util.h"
42 #include "content/public/browser/content_browser_client.h" 42 #include "content/public/browser/content_browser_client.h"
43 #include "content/public/browser/render_process_host.h" 43 #include "content/public/browser/render_process_host.h"
44 #include "content/public/common/content_switches.h" 44 #include "content/public/common/content_switches.h"
45 #include "content/public/common/main_function_params.h" 45 #include "content/public/common/main_function_params.h"
46 #include "content/public/common/result_codes.h" 46 #include "content/public/common/result_codes.h"
47 #include "content/public/common/startup_task_runner.h"
47 #include "crypto/nss_util.h" 48 #include "crypto/nss_util.h"
48 #include "media/audio/audio_manager.h" 49 #include "media/audio/audio_manager.h"
49 #include "media/base/media.h" 50 #include "media/base/media.h"
50 #include "media/midi/midi_manager.h" 51 #include "media/midi/midi_manager.h"
51 #include "net/base/network_change_notifier.h" 52 #include "net/base/network_change_notifier.h"
52 #include "net/socket/client_socket_factory.h" 53 #include "net/socket/client_socket_factory.h"
53 #include "net/ssl/ssl_config_service.h" 54 #include "net/ssl/ssl_config_service.h"
54 #include "ui/base/clipboard/clipboard.h" 55 #include "ui/base/clipboard/clipboard.h"
55 56
56 #if defined(USE_AURA) 57 #if defined(USE_AURA)
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 } 465 }
465 #endif 466 #endif
466 467
467 if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) { 468 if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) {
468 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver") 469 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver")
469 memory_observer_.reset(new MemoryObserver()); 470 memory_observer_.reset(new MemoryObserver());
470 base::MessageLoop::current()->AddTaskObserver(memory_observer_.get()); 471 base::MessageLoop::current()->AddTaskObserver(memory_observer_.get());
471 } 472 }
472 } 473 }
473 474
474 void BrowserMainLoop::CreateThreads() { 475 void BrowserMainLoop::CreateThread(size_t thread_id) {
475 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads") 476
477 base::Thread::Options default_options;
478 scoped_ptr<BrowserProcessSubThread>* thread_to_start = NULL;
479 base::Thread::Options* options = &default_options;
480
481 base::Thread::Options io_message_loop_options;
482 io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
483 base::Thread::Options ui_message_loop_options;
484 ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI;
485
486 switch (thread_id) {
487 case BrowserThread::DB:
488 TRACE_EVENT_BEGIN1("startup",
489 "BrowserMainLoop::CreateThread:start",
490 "Thread",
491 "BrowserThread::DB");
492 thread_to_start = &db_thread_;
493 break;
494 case BrowserThread::FILE_USER_BLOCKING:
495 TRACE_EVENT_BEGIN1("startup",
496 "BrowserMainLoop::CreateThread:start",
497 "Thread",
498 "BrowserThread::FILE_USER_BLOCKING");
499 thread_to_start = &file_user_blocking_thread_;
500 break;
501 case BrowserThread::FILE:
502 TRACE_EVENT_BEGIN1("startup",
503 "BrowserMainLoop::CreateThread:start",
504 "Thread",
505 "BrowserThread::FILE");
506 thread_to_start = &file_thread_;
507 #if defined(OS_WIN)
508 // On Windows, the FILE thread needs to be have a UI message loop
509 // which pumps messages in such a way that Google Update can
510 // communicate back to us.
511 options = &ui_message_loop_options;
512 #else
513 options = &io_message_loop_options;
514 #endif
515 break;
516 case BrowserThread::PROCESS_LAUNCHER:
517 TRACE_EVENT_BEGIN1("startup",
518 "BrowserMainLoop::CreateThread:start",
519 "Thread",
520 "BrowserThread::PROCESS_LAUNCHER");
521 thread_to_start = &process_launcher_thread_;
522 break;
523 case BrowserThread::CACHE:
524 TRACE_EVENT_BEGIN1("startup",
525 "BrowserMainLoop::CreateThread:start",
526 "Thread",
527 "BrowserThread::CACHE");
528 thread_to_start = &cache_thread_;
529 options = &io_message_loop_options;
530 break;
531 case BrowserThread::IO:
532 TRACE_EVENT_BEGIN1("startup",
533 "BrowserMainLoop::CreateThread:start",
534 "Thread",
535 "BrowserThread::IO");
536 thread_to_start = &io_thread_;
537 options = &io_message_loop_options;
538 break;
539 case BrowserThread::UI:
540 case BrowserThread::ID_COUNT:
541 default:
542 NOTREACHED();
543 break;
544 }
545
546 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id);
547
548 if (thread_to_start) {
549 (*thread_to_start).reset(new BrowserProcessSubThread(id));
550 (*thread_to_start)->StartWithOptions(*options);
551 } else {
552 NOTREACHED();
553 }
554
555 TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThread:start");
556 }
557
558 void BrowserMainLoop::PreCreateThreads() {
476 559
477 if (parts_) { 560 if (parts_) {
478 TRACE_EVENT0("startup", 561 TRACE_EVENT0("startup",
479 "BrowserMainLoop::CreateThreads:PreCreateThreads"); 562 "BrowserMainLoop::CreateThreads:PreCreateThreads");
480 result_code_ = parts_->PreCreateThreads(); 563 result_code_ = parts_->PreCreateThreads();
481 } 564 }
482 565
483 #if defined(ENABLE_PLUGINS) 566 #if defined(ENABLE_PLUGINS)
484 // Prior to any processing happening on the io thread, we create the 567 // Prior to any processing happening on the io thread, we create the
485 // plugin service as it is predominantly used from the io thread, 568 // plugin service as it is predominantly used from the io thread,
486 // but must be created on the main thread. The service ctor is 569 // but must be created on the main thread. The service ctor is
487 // inexpensive and does not invoke the io_thread() accessor. 570 // inexpensive and does not invoke the io_thread() accessor.
488 { 571 {
489 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService") 572 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService")
490 PluginService::GetInstance()->Init(); 573 PluginService::GetInstance()->Init();
491 } 574 }
492 #endif 575 #endif
493 576
494 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID)) 577 #if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID))
495 // Single-process is an unsupported and not fully tested mode, so 578 // Single-process is an unsupported and not fully tested mode, so
496 // don't enable it for official Chrome builds (except on Android). 579 // don't enable it for official Chrome builds (except on Android).
497 if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) 580 if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
498 RenderProcessHost::SetRunRendererInProcess(true); 581 RenderProcessHost::SetRunRendererInProcess(true);
499 #endif 582 #endif
583 }
500 584
501 if (result_code_ > 0) 585 void BrowserMainLoop::CreateThreads(
502 return; 586 const scoped_refptr<StartupTaskRunner>& task_runner) {
587 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads")
503 588
504 base::Thread::Options default_options; 589 task_runner->SetProxy(base::MessageLoop::current()->message_loop_proxy());
505 base::Thread::Options io_message_loop_options; 590
506 io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO; 591 base::Closure pre_create_threads =
507 base::Thread::Options ui_message_loop_options; 592 base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
508 ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI; 593 task_runner->AddTask(pre_create_threads);
509 594
510 // Start threads in the order they occur in the BrowserThread::ID 595 // Start threads in the order they occur in the BrowserThread::ID
511 // enumeration, except for BrowserThread::UI which is the main 596 // enumeration, except for BrowserThread::UI which is the main
512 // thread. 597 // thread.
513 // 598 //
514 // Must be size_t so we can increment it. 599 // Must be size_t so we can increment it.
515 for (size_t thread_id = BrowserThread::UI + 1; 600 for (size_t thread_id = BrowserThread::UI + 1;
516 thread_id < BrowserThread::ID_COUNT; 601 thread_id < BrowserThread::ID_COUNT;
517 ++thread_id) { 602 ++thread_id) {
518 scoped_ptr<BrowserProcessSubThread>* thread_to_start = NULL; 603 base::Closure create_thread = base::Bind(
519 base::Thread::Options* options = &default_options; 604 &BrowserMainLoop::CreateThread, base::Unretained(this), thread_id);
520 605 task_runner->AddTask(create_thread);
Yaron 2013/07/23 02:14:03 To jam's point, the two slow thread inits that I k
aberent 2013/07/23 13:45:03 The time for actual thread creation is now trivial
521 switch (thread_id) {
522 case BrowserThread::DB:
523 TRACE_EVENT_BEGIN1("startup",
524 "BrowserMainLoop::CreateThreads:start",
525 "Thread", "BrowserThread::DB");
526 thread_to_start = &db_thread_;
527 break;
528 case BrowserThread::FILE_USER_BLOCKING:
529 TRACE_EVENT_BEGIN1("startup",
530 "BrowserMainLoop::CreateThreads:start",
531 "Thread", "BrowserThread::FILE_USER_BLOCKING");
532 thread_to_start = &file_user_blocking_thread_;
533 break;
534 case BrowserThread::FILE:
535 TRACE_EVENT_BEGIN1("startup",
536 "BrowserMainLoop::CreateThreads:start",
537 "Thread", "BrowserThread::FILE");
538 thread_to_start = &file_thread_;
539 #if defined(OS_WIN)
540 // On Windows, the FILE thread needs to be have a UI message loop
541 // which pumps messages in such a way that Google Update can
542 // communicate back to us.
543 options = &ui_message_loop_options;
544 #else
545 options = &io_message_loop_options;
546 #endif
547 break;
548 case BrowserThread::PROCESS_LAUNCHER:
549 TRACE_EVENT_BEGIN1("startup",
550 "BrowserMainLoop::CreateThreads:start",
551 "Thread", "BrowserThread::PROCESS_LAUNCHER");
552 thread_to_start = &process_launcher_thread_;
553 break;
554 case BrowserThread::CACHE:
555 TRACE_EVENT_BEGIN1("startup",
556 "BrowserMainLoop::CreateThreads:start",
557 "Thread", "BrowserThread::CACHE");
558 thread_to_start = &cache_thread_;
559 options = &io_message_loop_options;
560 break;
561 case BrowserThread::IO:
562 TRACE_EVENT_BEGIN1("startup",
563 "BrowserMainLoop::CreateThreads:start",
564 "Thread", "BrowserThread::IO");
565 thread_to_start = &io_thread_;
566 options = &io_message_loop_options;
567 break;
568 case BrowserThread::UI:
569 case BrowserThread::ID_COUNT:
570 default:
571 NOTREACHED();
572 break;
573 }
574
575 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id);
576
577 if (thread_to_start) {
578 (*thread_to_start).reset(new BrowserProcessSubThread(id));
579 (*thread_to_start)->StartWithOptions(*options);
580 } else {
581 NOTREACHED();
582 }
583
584 TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start");
585
586 } 606 }
587 607
588 #if !defined(OS_IOS) 608 base::Closure browser_thread_started = base::Bind(
589 indexed_db_thread_.reset(new base::Thread("IndexedDB")); 609 &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
590 indexed_db_thread_->Start(); 610 task_runner->AddTask(browser_thread_started);
591 #endif
592 611
593 BrowserThreadsStarted(); 612 base::Closure pre_main_message_loop_run = base::Bind(
613 &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
614 task_runner->AddTask(pre_main_message_loop_run);
594 615
616 task_runner->StartRunningTasks();
617 }
618
619 void BrowserMainLoop::PreMainMessageLoopRun() {
595 if (parts_) { 620 if (parts_) {
596 TRACE_EVENT0("startup", 621 TRACE_EVENT0("startup",
597 "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun"); 622 "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
598 parts_->PreMainMessageLoopRun(); 623 parts_->PreMainMessageLoopRun();
599 } 624 }
600 625
601 // If the UI thread blocks, the whole UI is unresponsive. 626 // If the UI thread blocks, the whole UI is unresponsive.
602 // Do not allow disk IO from the UI thread. 627 // Do not allow disk IO from the UI thread.
603 base::ThreadRestrictions::SetIOAllowed(false); 628 base::ThreadRestrictions::SetIOAllowed(false);
604 base::ThreadRestrictions::DisallowWaiting(); 629 base::ThreadRestrictions::DisallowWaiting();
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 if (main_message_loop_) 771 if (main_message_loop_)
747 main_message_loop_->set_thread_name(kThreadName); 772 main_message_loop_->set_thread_name(kThreadName);
748 773
749 // Register the main thread by instantiating it, but don't call any methods. 774 // Register the main thread by instantiating it, but don't call any methods.
750 main_thread_.reset( 775 main_thread_.reset(
751 new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current())); 776 new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current()));
752 } 777 }
753 778
754 void BrowserMainLoop::BrowserThreadsStarted() { 779 void BrowserMainLoop::BrowserThreadsStarted() {
755 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted") 780 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted")
781
782 #if !defined(OS_IOS)
783 indexed_db_thread_.reset(new base::Thread("IndexedDB"));
784 indexed_db_thread_->Start();
785 #endif
786
756 #if defined(OS_ANDROID) 787 #if defined(OS_ANDROID)
757 // Up the priority of anything that touches with display tasks 788 // Up the priority of anything that touches with display tasks
758 // (this thread is UI thread, and io_thread_ is for IPCs). 789 // (this thread is UI thread, and io_thread_ is for IPCs).
759 io_thread_->SetPriority(base::kThreadPriority_Display); 790 io_thread_->SetPriority(base::kThreadPriority_Display);
760 base::PlatformThread::SetThreadPriority( 791 base::PlatformThread::SetThreadPriority(
761 base::PlatformThread::CurrentHandle(), 792 base::PlatformThread::CurrentHandle(),
762 base::kThreadPriority_Display); 793 base::kThreadPriority_Display);
763 #endif 794 #endif
764 795
765 #if !defined(OS_IOS) 796 #if !defined(OS_IOS)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 if (parameters_.ui_task) 918 if (parameters_.ui_task)
888 base::MessageLoopForUI::current()->PostTask(FROM_HERE, 919 base::MessageLoopForUI::current()->PostTask(FROM_HERE,
889 *parameters_.ui_task); 920 *parameters_.ui_task);
890 921
891 base::RunLoop run_loop; 922 base::RunLoop run_loop;
892 run_loop.Run(); 923 run_loop.Run();
893 #endif 924 #endif
894 } 925 }
895 926
896 } // namespace content 927 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698