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/logging.h" | 10 #include "base/logging.h" |
(...skipping 26 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |