Commit 840ab30d authored by Yuta Kitamura's avatar Yuta Kitamura Committed by Commit Bot

Let Platform own main thread in simple use cases.

Currently, the main thread WebThread is owned by the embedder. We'd
like to shift the ownership to Platform, so that we can stop exposing
WebThread to embedders.

As a first step, this patch introduces a new initialization method
Platform::CreateMainThreadAndInitialize(), which is parallel to
Platform::Initialize(). It is targeted to tests or other use cases
which only require a simple execution environment of Blink. Currently,
each embedder implements its own WebThread, but I'd like to unify
those and remove them from non-Blink code eventually.

The new CreateMainThreadAndInitialize() lets Platform own the main
thread WebThread object, unlike Initialize(). Currently, Platform
needs to handle two different cases: main thread owned or not owned,
but this is only temporary, and they will eventually converge to the
"owned" case.

As a test bed, v8_context_snapshot_generator is migrated to the
new initialization method.

Bug: 826203
Change-Id: I14436509f420a5d73f2ce64722f41da5756fa45b
Reviewed-on: https://chromium-review.googlesource.com/1163560
Commit-Queue: Yuta Kitamura <yutak@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581136}
parent 051bf03a
...@@ -141,6 +141,21 @@ class BLINK_PLATFORM_EXPORT Platform { ...@@ -141,6 +141,21 @@ class BLINK_PLATFORM_EXPORT Platform {
static void Initialize(Platform*, WebThread* main_thread); static void Initialize(Platform*, WebThread* main_thread);
static Platform* Current(); static Platform* Current();
// This is another entry point for embedders that only require single-
// threaded execution of Blink. This version automatically sets up Blink
// with a minimally viable implementation of WebThread for the main thread.
// The WebThread object is returned by Platform::CurrentThread(), therefore
// embedders do not need to override CurrentThread().
//
// When this function is used, the WebThread instance for the main thread
// is owned by Platform (unlike Initialize()).
//
// In the future, we would like to let Platform own the WebThread object for
// the main thread in all cases, as part of Blink Thread Initialization
// Cleanup project:
// https://docs.google.com/document/d/1ehd6Lp5czBzOCHWrDkL9x62gjdlrtbMtJqt_eRaauYo/edit?usp=sharing
static void CreateMainThreadAndInitialize(Platform*);
// Used to switch the current platform only for testing. // Used to switch the current platform only for testing.
// You should not pass in a Platform object that is not fully instantiated. // You should not pass in a Platform object that is not fully instantiated.
static void SetCurrentPlatformForTesting(Platform*); static void SetCurrentPlatformForTesting(Platform*);
...@@ -392,9 +407,13 @@ class BLINK_PLATFORM_EXPORT Platform { ...@@ -392,9 +407,13 @@ class BLINK_PLATFORM_EXPORT Platform {
// for any other purpose. // for any other purpose.
virtual std::unique_ptr<WebThread> CreateWebAudioThread(); virtual std::unique_ptr<WebThread> CreateWebAudioThread();
// Returns an interface to the current thread. This is owned by the // Returns an interface to the current thread. This is usually owned by the
// embedder. // embedder, except when CreateMainThreadAndInitialize() is used. See comments
virtual WebThread* CurrentThread() { return nullptr; } // above for details.
//
// The default implementation works only if CreateMainThreadAndInitialize() is
// used. Otherwise, the embedder *must* implement their own version.
virtual WebThread* CurrentThread();
// Returns a blame context for attributing top-level work which does not // Returns a blame context for attributing top-level work which does not
// belong to a particular frame scope. // belong to a particular frame scope.
...@@ -687,6 +706,17 @@ class BLINK_PLATFORM_EXPORT Platform { ...@@ -687,6 +706,17 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual ~Platform(); virtual ~Platform();
WebThread* main_thread_; WebThread* main_thread_;
private:
static void InitializeCommon(Platform* platform);
// We eventually want to let Platform own the main thread WebThread, but
// currently the main thread is owned in a few selected cases. This variable
// is non-null when the main thread is owned by Platform. The pointer value
// is the same as main_thread_.
//
// For details, see comments around CreateMainThreadAndInitialize() above.
std::unique_ptr<WebThread> owned_main_thread_;
}; };
} // namespace blink } // namespace blink
......
...@@ -47,6 +47,18 @@ BLINK_EXPORT void Initialize(Platform*, ...@@ -47,6 +47,18 @@ BLINK_EXPORT void Initialize(Platform*,
service_manager::BinderRegistry*, service_manager::BinderRegistry*,
WebThread* main_thread); WebThread* main_thread);
// The same as above, but this only supports simple single-threaded execution
// environment. The main thread WebThread object is owned by Platform when this
// version is used. This version is mainly for tests and other components
// requiring only the simple environment.
//
// When this version is used, your Platform implementation needs to follow
// a certain convention on CurrentThread(); see the comments at
// Platform::CreateMainThreadAndInitialize().
BLINK_EXPORT void CreateMainThreadAndInitialize(
Platform*,
service_manager::BinderRegistry*);
// Get the V8 Isolate for the main thread. // Get the V8 Isolate for the main thread.
// initialize must have been called first. // initialize must have been called first.
BLINK_EXPORT v8::Isolate* MainThreadIsolate(); BLINK_EXPORT v8::Isolate* MainThreadIsolate();
......
...@@ -73,22 +73,16 @@ class EndOfTaskRunner : public WebThread::TaskObserver { ...@@ -73,22 +73,16 @@ class EndOfTaskRunner : public WebThread::TaskObserver {
} }
}; };
} // namespace WebThread::TaskObserver* g_end_of_task_runner = nullptr;
static WebThread::TaskObserver* g_end_of_task_runner = nullptr;
static BlinkInitializer& GetBlinkInitializer() { BlinkInitializer& GetBlinkInitializer() {
DEFINE_STATIC_LOCAL(std::unique_ptr<BlinkInitializer>, initializer, DEFINE_STATIC_LOCAL(std::unique_ptr<BlinkInitializer>, initializer,
(std::make_unique<BlinkInitializer>())); (std::make_unique<BlinkInitializer>()));
return *initializer; return *initializer;
} }
void Initialize(Platform* platform, void InitializeCommon(Platform* platform,
service_manager::BinderRegistry* registry, service_manager::BinderRegistry* registry) {
WebThread* main_thread) {
DCHECK(registry);
Platform::Initialize(platform, main_thread);
#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && defined(OS_WIN) #if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && defined(OS_WIN)
// Reserve address space on 32 bit Windows, to make it likelier that large // Reserve address space on 32 bit Windows, to make it likelier that large
// array buffer allocations succeed. // array buffer allocations succeed.
...@@ -141,6 +135,23 @@ void Initialize(Platform* platform, ...@@ -141,6 +135,23 @@ void Initialize(Platform* platform,
} }
} }
} // namespace
void Initialize(Platform* platform,
service_manager::BinderRegistry* registry,
WebThread* main_thread) {
DCHECK(registry);
Platform::Initialize(platform, main_thread);
InitializeCommon(platform, registry);
}
void CreateMainThreadAndInitialize(Platform* platform,
service_manager::BinderRegistry* registry) {
DCHECK(registry);
Platform::CreateMainThreadAndInitialize(platform);
InitializeCommon(platform, registry);
}
void BlinkInitializer::RegisterInterfaces( void BlinkInitializer::RegisterInterfaces(
service_manager::BinderRegistry& registry) { service_manager::BinderRegistry& registry) {
ModulesInitializer::RegisterInterfaces(registry); ModulesInitializer::RegisterInterfaces(registry);
......
...@@ -114,12 +114,44 @@ Platform::Platform() : main_thread_(nullptr) { ...@@ -114,12 +114,44 @@ Platform::Platform() : main_thread_(nullptr) {
Platform::~Platform() = default; Platform::~Platform() = default;
namespace {
class SingleThreadedWebThread : public WebThread {
public:
bool IsCurrentThread() const override {
DCHECK(WTF::IsMainThread());
return true;
}
ThreadScheduler* Scheduler() const override {
// TODO(yutak): Implement default scheduler.
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override {
DCHECK(WTF::IsMainThread());
return base::ThreadTaskRunnerHandle::Get();
}
};
} // namespace
void Platform::Initialize(Platform* platform, WebThread* main_thread) { void Platform::Initialize(Platform* platform, WebThread* main_thread) {
DCHECK(!g_platform); DCHECK(!g_platform);
DCHECK(platform); DCHECK(platform);
g_platform = platform; g_platform = platform;
g_platform->main_thread_ = main_thread; g_platform->main_thread_ = main_thread;
InitializeCommon(platform);
}
void Platform::CreateMainThreadAndInitialize(Platform* platform) {
DCHECK(!g_platform);
DCHECK(platform);
g_platform = platform;
g_platform->owned_main_thread_ = std::make_unique<SingleThreadedWebThread>();
g_platform->main_thread_ = g_platform->owned_main_thread_.get();
InitializeCommon(platform);
}
void Platform::InitializeCommon(Platform* platform) {
WTF::Initialize(CallOnMainThreadFunction); WTF::Initialize(CallOnMainThreadFunction);
ProcessHeap::Init(); ProcessHeap::Init();
...@@ -175,6 +207,13 @@ WebThread* Platform::MainThread() const { ...@@ -175,6 +207,13 @@ WebThread* Platform::MainThread() const {
return main_thread_; return main_thread_;
} }
WebThread* Platform::CurrentThread() {
// This version must be called only if the main thread is owned by Platform.
// See the comments in the header.
DCHECK(owned_main_thread_);
return main_thread_;
}
service_manager::Connector* Platform::GetConnector() { service_manager::Connector* Platform::GetConnector() {
DEFINE_STATIC_LOCAL(DefaultConnector, connector, ()); DEFINE_STATIC_LOCAL(DefaultConnector, connector, ());
return connector.Get(); return connector.Get();
......
...@@ -21,22 +21,9 @@ namespace { ...@@ -21,22 +21,9 @@ namespace {
constexpr char kPredictableFlag[] = "--predictable"; constexpr char kPredictableFlag[] = "--predictable";
class SnapshotThread : public blink::WebThread {
public:
bool IsCurrentThread() const override { return true; }
blink::ThreadScheduler* Scheduler() const override { return nullptr; }
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override {
return base::ThreadTaskRunnerHandle::Get();
}
};
class SnapshotPlatform final : public blink::Platform { class SnapshotPlatform final : public blink::Platform {
public: public:
bool IsTakingV8ContextSnapshot() override { return true; } bool IsTakingV8ContextSnapshot() override { return true; }
blink::WebThread* CurrentThread() override {
static SnapshotThread dummy_thread;
return &dummy_thread;
}
}; };
} // namespace } // namespace
...@@ -65,7 +52,7 @@ int main(int argc, char** argv) { ...@@ -65,7 +52,7 @@ int main(int argc, char** argv) {
// Take a snapshot. // Take a snapshot.
SnapshotPlatform platform; SnapshotPlatform platform;
service_manager::BinderRegistry empty_registry; service_manager::BinderRegistry empty_registry;
blink::Initialize(&platform, &empty_registry, platform.CurrentThread()); blink::CreateMainThreadAndInitialize(&platform, &empty_registry);
v8::StartupData blob = blink::WebV8ContextSnapshot::TakeSnapshot(); v8::StartupData blob = blink::WebV8ContextSnapshot::TakeSnapshot();
// Save the snapshot as a file. Filename is given in a command line option. // Save the snapshot as a file. Filename is given in a command line option.
......
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