Commit 4090dcce authored by Xi Han's avatar Xi Han Committed by Commit Bot

Plumb pre-created service manager thread when creating BrowserMainLoop.

The service manager thread and (TODO) ServiceManager might be created
before the full browser starts, and we want to reuse them when starting
the full browser. Therefore, we add a pointer of BrowserStartupData in
MainFunctionParams.

Particularly, in this CL, ContentMainRunnerImpl creates and owns a
BrowserStartupData object. It passes a pointer of the BrowserStartupData
through the main function parameter to BrowserMainLoop.

The BrowserStartupData interface was introduced in:
https://crrev.com/c/1117471.

Bug: 846846, 853308
Change-Id: Ie11063227a670cd8d72935131e854ee2b5c46e4e
Reviewed-on: https://chromium-review.googlesource.com/1108178
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@{#574054}
parent 513386a1
......@@ -42,6 +42,7 @@
#include "components/tracing/common/trace_startup.h"
#include "content/app/mojo/mojo_init.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/startup_data_impl.h"
#include "content/common/url_schemes.h"
#include "content/public/app/content_main_delegate.h"
#include "content/public/common/content_constants.h"
......@@ -580,10 +581,8 @@ static void RegisterMainThreadFactories() {
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
// Run the main function for browser process.
// Returns the exit code for this process.
int RunBrowserProcessMain(
const MainFunctionParams& main_function_params,
ContentMainDelegate* delegate,
std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
int RunBrowserProcessMain(const MainFunctionParams& main_function_params,
ContentMainDelegate* delegate) {
int exit_code = delegate->RunProcess("", main_function_params);
#if defined(OS_ANDROID)
// In Android's browser process, the negative exit code doesn't mean the
......@@ -594,10 +593,7 @@ int RunBrowserProcessMain(
#else
if (exit_code >= 0)
return exit_code;
// GetServiceManagerTaskRunnerForEmbedderProcess() needs to be invoked before
// Run() for the browser process.
DCHECK(service_manager_thread);
return BrowserMain(main_function_params, std::move(service_manager_thread));
return BrowserMain(main_function_params);
#endif
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
......@@ -927,6 +923,10 @@ int ContentMainRunnerImpl::Run() {
// The thread used to start the ServiceManager is handed-off to
// BrowserMain() which may elect to promote it (e.g. to BrowserThread::IO).
if (process_type.empty()) {
startup_data_ = std::make_unique<StartupDataImpl>();
startup_data_->thread = BrowserProcessSubThread::CreateIOThread();
main_params.startup_data = startup_data_.get();
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
// Create the TaskScheduler early to allow upcoming code to use
// the post_task.h API. Note: This is okay because RunBrowserProcessMain()
......@@ -944,8 +944,7 @@ int ContentMainRunnerImpl::Run() {
if (!base::MessageLoopCurrentForUI::IsSet())
main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
return RunBrowserProcessMain(main_params, delegate_,
std::move(service_manager_thread_));
return RunBrowserProcessMain(main_params, delegate_);
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
......@@ -980,14 +979,6 @@ void ContentMainRunnerImpl::Shutdown() {
is_shutdown_ = true;
}
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
scoped_refptr<base::SingleThreadTaskRunner>
ContentMainRunnerImpl::GetServiceManagerTaskRunnerForEmbedderProcess() {
service_manager_thread_ = BrowserProcessSubThread::CreateIOThread();
return service_manager_thread_->task_runner();
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
// static
ContentMainRunner* ContentMainRunner::Create() {
return ContentMainRunnerImpl::Create();
......
......@@ -11,6 +11,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "content/browser/startup_data_impl.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/common/content_client.h"
......@@ -23,11 +24,9 @@
namespace base {
class AtExitManager;
class SingleThreadTaskRunner;
} // namespace base
namespace content {
class BrowserProcessSubThread;
class ContentMainDelegate;
struct ContentMainParams;
......@@ -45,13 +44,6 @@ class ContentMainRunnerImpl : public ContentMainRunner {
int Run() override;
void Shutdown() override;
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
// Creates a thread and returns the SingleThreadTaskRunner on which
// ServiceManager should run.
scoped_refptr<base::SingleThreadTaskRunner>
GetServiceManagerTaskRunnerForEmbedderProcess();
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
private:
// True if the runner has been initialized.
bool is_initialized_ = false;
......@@ -76,14 +68,14 @@ class ContentMainRunnerImpl : public ContentMainRunner {
base::mac::ScopedNSAutoreleasePool* autorelease_pool_ = nullptr;
#endif
std::unique_ptr<BrowserProcessSubThread> service_manager_thread_;
base::Closure* ui_task_ = nullptr;
CreatedMainPartsClosure* created_main_parts_closure_ = nullptr;
std::unique_ptr<base::MessageLoop> main_message_loop_;
std::unique_ptr<StartupDataImpl> startup_data_;
DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
};
......
......@@ -126,11 +126,4 @@ ContentServiceManagerMainDelegate::CreateEmbeddedService(
return nullptr;
}
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
scoped_refptr<base::SingleThreadTaskRunner> ContentServiceManagerMainDelegate::
GetServiceManagerTaskRunnerForEmbedderProcess() {
return content_main_runner_->GetServiceManagerTaskRunnerForEmbedderProcess();
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
} // namespace content
......@@ -25,10 +25,6 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
// service_manager::MainDelegate:
int Initialize(const InitializeParams& params) override;
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
scoped_refptr<base::SingleThreadTaskRunner>
GetServiceManagerTaskRunnerForEmbedderProcess() override;
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
bool IsEmbedderSubprocess() override;
int RunEmbedderProcess() override;
void ShutDownEmbedderProcess() override;
......
......@@ -8,7 +8,6 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/browser_main_runner_impl.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/common/content_constants_internal.h"
namespace content {
......@@ -31,9 +30,7 @@ class ScopedBrowserMainEvent {
} // namespace
// Main routine for running as the Browser process.
int BrowserMain(
const MainFunctionParams& parameters,
std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
int BrowserMain(const MainFunctionParams& parameters) {
ScopedBrowserMainEvent scoped_browser_main_event;
base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
......@@ -43,8 +40,7 @@ int BrowserMain(
std::unique_ptr<BrowserMainRunnerImpl> main_runner(
BrowserMainRunnerImpl::Create());
int exit_code =
main_runner->Initialize(parameters, std::move(service_manager_thread));
int exit_code = main_runner->Initialize(parameters);
if (exit_code >= 0)
return exit_code;
......
......@@ -11,12 +11,9 @@
namespace content {
class BrowserProcessSubThread;
struct MainFunctionParams;
CONTENT_EXPORT int BrowserMain(
const content::MainFunctionParams& parameters,
std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
CONTENT_EXPORT int BrowserMain(const content::MainFunctionParams& parameters);
} // namespace content
......
......@@ -85,6 +85,7 @@
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/startup_data_impl.h"
#include "content/browser/startup_task_runner.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
......@@ -557,13 +558,20 @@ BrowserMainLoop::~BrowserMainLoop() {
g_current_browser_main_loop = nullptr;
}
void BrowserMainLoop::Init(
std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
void BrowserMainLoop::Init() {
TRACE_EVENT0("startup", "BrowserMainLoop::Init");
// This is always invoked before |io_thread_| is initialized (i.e. never
// resets it).
io_thread_ = std::move(service_manager_thread);
// |startup_data| is optional. If set, the thread owned by the data
// will be registered as BrowserThread::IO in CreateThreads() instead of
// creating a brand new thread.
if (parameters_.startup_data) {
StartupDataImpl* startup_data =
static_cast<StartupDataImpl*>(parameters_.startup_data);
// This is always invoked before |io_thread_| is initialized (i.e. never
// resets it).
io_thread_ = std::move(startup_data->thread);
}
parts_.reset(
GetContentClient()->browser()->CreateBrowserMainParts(parameters_));
}
......
......@@ -127,10 +127,7 @@ class CONTENT_EXPORT BrowserMainLoop {
explicit BrowserMainLoop(const MainFunctionParams& parameters);
virtual ~BrowserMainLoop();
// |service_manager_thread| is optional. If set, it will be registered as
// BrowserThread::IO in CreateThreads() instead of creating a brand new
// thread.
void Init(std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
void Init();
// Return value is exit status. Anything other than RESULT_CODE_NORMAL_EXIT
// is considered an error.
......
......@@ -29,7 +29,7 @@ TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
*scoped_command_line.GetProcessCommandLine());
BrowserMainLoop browser_main_loop(main_function_params);
browser_main_loop.MainMessageLoopStart();
browser_main_loop.Init(nullptr);
browser_main_loop.Init();
browser_main_loop.CreateThreads();
EXPECT_GE(base::TaskScheduler::GetInstance()
->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
......
......@@ -23,7 +23,6 @@
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/browser_shutdown_profile_dumper.h"
#include "content/browser/notification_service_impl.h"
#include "content/common/content_switches_internal.h"
......@@ -63,12 +62,6 @@ BrowserMainRunnerImpl::~BrowserMainRunnerImpl() {
}
int BrowserMainRunnerImpl::Initialize(const MainFunctionParams& parameters) {
return Initialize(parameters, nullptr);
}
int BrowserMainRunnerImpl::Initialize(
const MainFunctionParams& parameters,
std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
SCOPED_UMA_HISTOGRAM_LONG_TIMER(
"Startup.BrowserMainRunnerImplInitializeLongTime");
TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize");
......@@ -117,7 +110,7 @@ int BrowserMainRunnerImpl::Initialize(
main_loop_.reset(new BrowserMainLoop(parameters));
main_loop_->Init(std::move(service_manager_thread));
main_loop_->Init();
if (parameters.created_main_parts_closure) {
parameters.created_main_parts_closure->Run(main_loop_->parts());
......
......@@ -19,7 +19,6 @@ class ScopedOleInitializer;
namespace content {
class BrowserProcessSubThread;
class BrowserMainLoop;
class NotificationServiceImpl;
......@@ -38,12 +37,6 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
int Run() override;
void Shutdown() override;
// Initialize all necessary browser state with a |service_manager_thread|
// on which ServiceManager is currently running.
int Initialize(
const MainFunctionParams& parameters,
std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
private:
// True if we have started to initialize the runner.
bool initialization_started_;
......
......@@ -28,6 +28,7 @@ class ScopedNSAutoreleasePool;
namespace content {
class BrowserMainParts;
struct StartupData;
using CreatedMainPartsClosure = base::Callback<void(BrowserMainParts*)>;
......@@ -56,6 +57,10 @@ struct MainFunctionParams {
// Used by InProcessBrowserTest. If non-null this is Run() after
// BrowserMainParts has been created and before PreEarlyInitialization().
CreatedMainPartsClosure* created_main_parts_closure = nullptr;
// Used by //content, when the embedder yields control back to it, to extract
// startup data passed from ContentMainRunner.
StartupData* startup_data = nullptr;
};
} // namespace content
......
......@@ -23,7 +23,6 @@
#include "base/test/test_timeouts.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
#include "content/public/app/content_main.h"
......@@ -124,8 +123,7 @@ class InitialNavigationObserver : public WebContentsObserver {
} // namespace
extern int BrowserMain(const MainFunctionParams&,
std::unique_ptr<BrowserProcessSubThread> io_thread);
extern int BrowserMain(const MainFunctionParams&);
BrowserTestBase::BrowserTestBase()
: field_trial_list_(std::make_unique<base::FieldTrialList>(nullptr)),
......@@ -324,7 +322,7 @@ void BrowserTestBase::SetUp() {
params.created_main_parts_closure = created_main_parts_closure.release();
base::TaskScheduler::Create("Browser");
// TODO(phajdan.jr): Check return code, http://crbug.com/374738 .
BrowserMain(params, nullptr);
BrowserMain(params);
#else
GetContentMainParams()->ui_task = ui_task.release();
GetContentMainParams()->created_main_parts_closure =
......
......@@ -449,13 +449,6 @@ int Main(const MainParams& params) {
case ProcessType::kEmbedder:
if (delegate->IsEmbedderSubprocess())
CommonSubprocessInit();
if (command_line.GetSwitchValueASCII(switches::kProcessType).empty()) {
// TODO(https://crbug.com/729596): Use this task runner to start
// ServiceManager.
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
delegate->GetServiceManagerTaskRunnerForEmbedderProcess();
}
exit_code = delegate->RunEmbedderProcess();
break;
}
......
......@@ -10,14 +10,6 @@ MainDelegate::MainDelegate() = default;
MainDelegate::~MainDelegate() = default;
scoped_refptr<base::SingleThreadTaskRunner>
MainDelegate::GetServiceManagerTaskRunnerForEmbedderProcess() {
// The default implementation is provided for compiling purpose on Windows and
// should never be called.
NOTREACHED();
return nullptr;
}
bool MainDelegate::IsEmbedderSubprocess() {
return false;
}
......
......@@ -49,11 +49,6 @@ class SERVICE_MANAGER_EMBEDDER_EXPORT MainDelegate {
// failure.
virtual int Initialize(const InitializeParams& params) = 0;
// Creates an thread and returns the SingleThreadTaskRunner on which
// ServiceManager should run.
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetServiceManagerTaskRunnerForEmbedderProcess();
// Indicates whether this (embedder) process should be treated as a subprocess
// for the sake of some platform-specific environment initialization details.
virtual bool IsEmbedderSubprocess();
......
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