Commit aa60c219 authored by Xi Han's avatar Xi Han Committed by Commit Bot

Start ServiceManger before creating BrowserMainLoop.

This CL instantiates the ServiceManagerContext before creating
the BrowserMainRunner. It splits the startup path into two,
with/without starting the full browser. The changes are implemented
behind a flag "allow-start-service-manager-only".

Bug: 846846,729596
Change-Id: I3584db0d89a10e59d6041e0f4412aaffdc840568
Reviewed-on: https://chromium-review.googlesource.com/c/1113802
Commit-Queue: Xi Han <hanxi@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603092}
parent e015ed70
include_rules = [ include_rules = [
"+components/download",
"+components/tracing", "+components/tracing",
"+content", "+content",
"+device/bluetooth", "+device/bluetooth",
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "components/download/public/common/download_task_runner.h"
#include "components/tracing/common/trace_startup.h" #include "components/tracing/common/trace_startup.h"
#include "content/app/mojo/mojo_init.h" #include "content/app/mojo/mojo_init.h"
#include "content/browser/browser_process_sub_thread.h" #include "content/browser/browser_process_sub_thread.h"
...@@ -153,6 +154,10 @@ ...@@ -153,6 +154,10 @@
#include "services/service_manager/zygote/host/zygote_host_impl_linux.h" #include "services/service_manager/zygote/host/zygote_host_impl_linux.h"
#endif #endif
#if defined(OS_ANDROID)
#include "content/browser/android/browser_startup_controller.h"
#endif
namespace content { namespace content {
extern int GpuMain(const content::MainFunctionParams&); extern int GpuMain(const content::MainFunctionParams&);
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
...@@ -167,6 +172,11 @@ namespace content { ...@@ -167,6 +172,11 @@ namespace content {
namespace { namespace {
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
const char kAllowStartingServiceManagerOnly[] =
"allow-start-service-manager-only";
#endif
#if defined(V8_USE_EXTERNAL_STARTUP_DATA) && defined(OS_ANDROID) #if defined(V8_USE_EXTERNAL_STARTUP_DATA) && defined(OS_ANDROID)
#if defined __LP64__ #if defined __LP64__
#define kV8SnapshotDataDescriptor kV8Snapshot64DataDescriptor #define kV8SnapshotDataDescriptor kV8Snapshot64DataDescriptor
...@@ -854,13 +864,20 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) { ...@@ -854,13 +864,20 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
RegisterMainThreadFactories(); RegisterMainThreadFactories();
#if !defined(CHROME_MULTIPLE_DLL_CHILD) #if !defined(CHROME_MULTIPLE_DLL_CHILD)
// The thread used to start the ServiceManager is handed-off to if (process_type.empty())
// BrowserMain() which may elect to promote it (e.g. to BrowserThread::IO). return RunServiceManager(main_params, start_service_manager_only);
if (process_type.empty()) { #endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
startup_data_ = std::make_unique<StartupDataImpl>();
startup_data_->thread = BrowserProcessSubThread::CreateIOThread(); return RunOtherNamedProcessTypeMain(process_type, main_params, delegate_);
main_params.startup_data = startup_data_.get(); }
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
int ContentMainRunnerImpl::RunServiceManager(MainFunctionParams& main_params,
bool start_service_manager_only) {
if (is_browser_main_loop_started_)
return -1;
if (!service_manager_context_) {
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) { if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
// Create and start the TaskScheduler early to allow upcoming code to use // Create and start the TaskScheduler early to allow upcoming code to use
// the post_task.h API. // the post_task.h API.
...@@ -899,12 +916,32 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) { ...@@ -899,12 +916,32 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
// incorrect to post to a BrowserThread before this point. // incorrect to post to a BrowserThread before this point.
BrowserTaskExecutor::Create(); BrowserTaskExecutor::Create();
return RunBrowserProcessMain(main_params, delegate_); // The thread used to start the ServiceManager is handed-off to
// BrowserMain() which may elect to promote it (e.g. to BrowserThread::IO).
service_manager_thread_ = BrowserProcessSubThread::CreateIOThread();
service_manager_context_.reset(
new ServiceManagerContext(service_manager_thread_->task_runner()));
download::SetIOTaskRunner(service_manager_thread_->task_runner());
#if defined(OS_ANDROID)
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&ServiceManagerStartupComplete));
#endif
} }
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
return RunOtherNamedProcessTypeMain(process_type, main_params, delegate_); if (base::CommandLine::ForCurrentProcess()->HasSwitch(
kAllowStartingServiceManagerOnly) &&
start_service_manager_only) {
return -1;
}
is_browser_main_loop_started_ = true;
startup_data_ = std::make_unique<StartupDataImpl>();
startup_data_->thread = std::move(service_manager_thread_);
startup_data_->service_manager_context = service_manager_context_.get();
main_params.startup_data = startup_data_.get();
return RunBrowserProcessMain(main_params, delegate_);
} }
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
void ContentMainRunnerImpl::Shutdown() { void ContentMainRunnerImpl::Shutdown() {
DCHECK(is_initialized_); DCHECK(is_initialized_);
......
...@@ -12,10 +12,12 @@ ...@@ -12,10 +12,12 @@
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/startup_data_impl.h" #include "content/browser/startup_data_impl.h"
#include "content/public/app/content_main.h" #include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h" #include "content/public/app/content_main_runner.h"
#include "content/public/common/content_client.h" #include "content/public/common/content_client.h"
#include "content/public/common/main_function_params.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/sandbox_types.h"
...@@ -46,6 +48,20 @@ class ContentMainRunnerImpl : public ContentMainRunner { ...@@ -46,6 +48,20 @@ class ContentMainRunnerImpl : public ContentMainRunner {
void Shutdown() override; void Shutdown() override;
private: private:
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
int RunServiceManager(MainFunctionParams& main_function_params,
bool start_service_manager_only);
bool is_browser_main_loop_started_ = false;
std::unique_ptr<base::MessageLoop> main_message_loop_;
std::unique_ptr<StartupDataImpl> startup_data_;
std::unique_ptr<base::FieldTrialList> field_trial_list_;
std::unique_ptr<BrowserProcessSubThread> service_manager_thread_;
std::unique_ptr<ServiceManagerContext> service_manager_context_;
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
// True if the runner has been initialized. // True if the runner has been initialized.
bool is_initialized_ = false; bool is_initialized_ = false;
...@@ -73,14 +89,6 @@ class ContentMainRunnerImpl : public ContentMainRunner { ...@@ -73,14 +89,6 @@ class ContentMainRunnerImpl : public ContentMainRunner {
CreatedMainPartsClosure* created_main_parts_closure_ = nullptr; CreatedMainPartsClosure* created_main_parts_closure_ = nullptr;
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
std::unique_ptr<base::MessageLoop> main_message_loop_;
std::unique_ptr<StartupDataImpl> startup_data_;
std::unique_ptr<base::FieldTrialList> field_trial_list_;
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl); DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
}; };
......
...@@ -561,6 +561,7 @@ void BrowserMainLoop::Init() { ...@@ -561,6 +561,7 @@ void BrowserMainLoop::Init() {
// This is always invoked before |io_thread_| is initialized (i.e. never // This is always invoked before |io_thread_| is initialized (i.e. never
// resets it). // resets it).
io_thread_ = std::move(startup_data->thread); io_thread_ = std::move(startup_data->thread);
service_manager_context_ = startup_data->service_manager_context;
} }
parts_.reset( parts_.reset(
...@@ -1081,7 +1082,8 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { ...@@ -1081,7 +1082,8 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
BrowserGpuChannelHostFactory::instance()->CloseChannel(); BrowserGpuChannelHostFactory::instance()->CloseChannel();
// Shutdown the Service Manager and IPC. // Shutdown the Service Manager and IPC.
service_manager_context_.reset(); service_manager_context_->ShutDown();
owned_service_manager_context_.reset();
mojo_ipc_support_.reset(); mojo_ipc_support_.reset();
if (save_file_manager_) if (save_file_manager_)
...@@ -1537,9 +1539,13 @@ void BrowserMainLoop::InitializeMojo() { ...@@ -1537,9 +1539,13 @@ void BrowserMainLoop::InitializeMojo() {
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST)); mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
service_manager_context_.reset( if (!service_manager_context_) {
new ServiceManagerContext(io_thread_->task_runner())); owned_service_manager_context_ =
std::make_unique<ServiceManagerContext>(io_thread_->task_runner());
service_manager_context_ = owned_service_manager_context_.get();
}
ServiceManagerContext::StartBrowserConnection(); ServiceManagerContext::StartBrowserConnection();
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
mojo::core::SetMachPortProvider(MachBroker::GetInstance()); mojo::core::SetMachPortProvider(MachBroker::GetInstance());
#endif // defined(OS_MACOSX) #endif // defined(OS_MACOSX)
......
...@@ -351,8 +351,10 @@ class CONTENT_EXPORT BrowserMainLoop { ...@@ -351,8 +351,10 @@ class CONTENT_EXPORT BrowserMainLoop {
gpu_data_manager_visual_proxy_; gpu_data_manager_visual_proxy_;
#endif #endif
ServiceManagerContext* service_manager_context_ = nullptr;
std::unique_ptr<ServiceManagerContext> owned_service_manager_context_;
// Members initialized in |BrowserThreadsStarted()| -------------------------- // Members initialized in |BrowserThreadsStarted()| --------------------------
std::unique_ptr<ServiceManagerContext> service_manager_context_;
std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_; std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_;
// |user_input_monitor_| has to outlive |audio_manager_|, so declared first. // |user_input_monitor_| has to outlive |audio_manager_|, so declared first.
......
...@@ -37,6 +37,7 @@ TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) { ...@@ -37,6 +37,7 @@ TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
browser_main_loop.MainMessageLoopStart(); browser_main_loop.MainMessageLoopStart();
browser_main_loop.Init(); browser_main_loop.Init();
browser_main_loop.CreateThreads(); browser_main_loop.CreateThreads();
browser_main_loop.InitializeMojo();
EXPECT_GE(base::TaskScheduler::GetInstance() EXPECT_GE(base::TaskScheduler::GetInstance()
->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( ->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
{base::TaskPriority::USER_VISIBLE}), {base::TaskPriority::USER_VISIBLE}),
......
...@@ -763,6 +763,10 @@ ServiceManagerContext::ServiceManagerContext( ...@@ -763,6 +763,10 @@ ServiceManagerContext::ServiceManagerContext(
} }
ServiceManagerContext::~ServiceManagerContext() { ServiceManagerContext::~ServiceManagerContext() {
ShutDown();
}
void ServiceManagerContext::ShutDown() {
// NOTE: The in-process ServiceManager MUST be destroyed before the browser // NOTE: The in-process ServiceManager MUST be destroyed before the browser
// process-wide ServiceManagerConnection. Otherwise it's possible for the // process-wide ServiceManagerConnection. Otherwise it's possible for the
// ServiceManager to receive connection requests for service:content_browser // ServiceManager to receive connection requests for service:content_browser
...@@ -773,6 +777,7 @@ ServiceManagerContext::~ServiceManagerContext() { ...@@ -773,6 +777,7 @@ ServiceManagerContext::~ServiceManagerContext() {
ServiceManagerConnection::DestroyForProcess(); ServiceManagerConnection::DestroyForProcess();
service_manager_thread_task_runner_->PostTask( service_manager_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&DestroyConnectorOnIOThread)); FROM_HERE, base::BindOnce(&DestroyConnectorOnIOThread));
packaged_services_connection_.reset();
} }
// static // static
...@@ -796,22 +801,12 @@ void ServiceManagerContext::StartBrowserConnection() { ...@@ -796,22 +801,12 @@ void ServiceManagerContext::StartBrowserConnection() {
RegisterCommonBrowserInterfaces(browser_connection); RegisterCommonBrowserInterfaces(browser_connection);
browser_connection->Start(); browser_connection->Start();
bool network_service_enabled = if (base::FeatureList::IsEnabled(network::features::kNetworkService))
base::FeatureList::IsEnabled(network::features::kNetworkService); return;
bool network_service_in_process =
base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) ||
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess);
if (!network_service_enabled) {
// Create the in-process NetworkService object so that its getter is // Create the in-process NetworkService object so that its getter is
// available on the IO thread. // available on the IO thread.
GetNetworkService(); GetNetworkService();
} else if (!network_service_in_process) {
// Start the network service process as soon as possible, since it is
// critical to start up performance.
browser_connection->GetConnector()->StartService(
mojom::kNetworkServiceName);
}
} }
// static // static
......
...@@ -50,6 +50,9 @@ class CONTENT_EXPORT ServiceManagerContext { ...@@ -50,6 +50,9 @@ class CONTENT_EXPORT ServiceManagerContext {
static base::DeferredSequencedTaskRunner* GetAudioServiceRunner(); static base::DeferredSequencedTaskRunner* GetAudioServiceRunner();
// Shutdowns the ServiceManager and the connections to the ServiceManager.
void ShutDown();
private: private:
class InProcessServiceManagerContext; class InProcessServiceManagerContext;
......
...@@ -12,13 +12,15 @@ ...@@ -12,13 +12,15 @@
namespace content { namespace content {
class ServiceManagerContext;
// The browser implementation of StartupData. // The browser implementation of StartupData.
struct StartupDataImpl : public StartupData { struct StartupDataImpl : public StartupData {
StartupDataImpl(); StartupDataImpl();
~StartupDataImpl() override; ~StartupDataImpl() override;
// TODO(hanxi): add ServiceManagerContext* here.
std::unique_ptr<BrowserProcessSubThread> thread; std::unique_ptr<BrowserProcessSubThread> thread;
ServiceManagerContext* service_manager_context;
}; };
} // namespace content } // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment