0

Move thread-local store for WebThreads to Platform.

This CL moves the thread-local storage for Blink threads currently
stored in content::BlinkPlatformImpl to Platform, so that //content's
dependency to WebThread could be reduced further.

The responsibility of creating a physical thread (i.e. base::Thread)
is now shifted to Platform::CreateThread(). Platform also manages
the thread-local storage of WebThreads, making it possible for Platform
to implement CurrentThread() itself.

Platform::CreateThread() and CurrentThread() are no longer virtual;
now they are concrete functions implemented in Platform. It's a bit
unfortunate to have a fat implementation in Platform like this,
because Platform should be a pure interface to embedders. Eventually
we would like to move them to somewhere in platform/.

Bug: 826203
Change-Id: I4406c2f964f0e41e59ef367269b000e81eeb53aa
Reviewed-on: https://chromium-review.googlesource.com/1238094
Commit-Queue: Yuta Kitamura <yutak@chromium.org>
Reviewed-by: Alexander Timin <altimin@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594221}
This commit is contained in:
Yuta Kitamura
2018-09-26 04:53:19 +00:00
committed by Commit Bot
parent ab062c62b1
commit 477a39d0c8
20 changed files with 87 additions and 205 deletions

@@ -23,10 +23,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump_guid.h" #include "base/trace_event/memory_allocator_dump_guid.h"
@@ -359,57 +356,9 @@ BlinkPlatformImpl::BlinkPlatformImpl(
: main_thread_task_runner_(std::move(main_thread_task_runner)), : main_thread_task_runner_(std::move(main_thread_task_runner)),
io_thread_task_runner_(std::move(io_thread_task_runner)) {} io_thread_task_runner_(std::move(io_thread_task_runner)) {}
void BlinkPlatformImpl::WaitUntilWebThreadTLSUpdate(
blink::scheduler::WebThreadBase* thread) {
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
thread->GetTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&BlinkPlatformImpl::UpdateWebThreadTLS,
base::Unretained(this), base::Unretained(thread),
base::Unretained(&event)));
event.Wait();
}
void BlinkPlatformImpl::UpdateWebThreadTLS(blink::WebThread* thread,
base::WaitableEvent* event) {
DCHECK(!current_thread_slot_.Get());
current_thread_slot_.Set(thread);
event->Signal();
}
BlinkPlatformImpl::~BlinkPlatformImpl() { BlinkPlatformImpl::~BlinkPlatformImpl() {
} }
std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateThread(
const blink::WebThreadCreationParams& params) {
std::unique_ptr<blink::scheduler::WebThreadBase> thread =
blink::scheduler::WebThreadBase::CreateWorkerThread(params);
thread->Init();
WaitUntilWebThreadTLSUpdate(thread.get());
return std::move(thread);
}
std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateWebAudioThread() {
blink::WebThreadCreationParams params(blink::WebThreadType::kWebAudioThread);
// WebAudio uses a thread with |DISPLAY| priority to avoid glitch when the
// system is under the high pressure. Note that the main browser thread also
// runs with same priority. (see: crbug.com/734539)
params.thread_options.priority = base::ThreadPriority::DISPLAY;
std::unique_ptr<blink::scheduler::WebThreadBase> thread =
blink::scheduler::WebThreadBase::CreateWorkerThread(params);
thread->Init();
WaitUntilWebThreadTLSUpdate(thread.get());
return std::move(thread);
}
blink::WebThread* BlinkPlatformImpl::CurrentThread() {
// TODO(yutak): This only works on non-main threads. We can support
// the main thread here as well.
return static_cast<blink::WebThread*>(current_thread_slot_.Get());
}
void BlinkPlatformImpl::RecordAction(const blink::UserMetricsAction& name) { void BlinkPlatformImpl::RecordAction(const blink::UserMetricsAction& name) {
if (ChildThread* child_thread = ChildThread::Get()) if (ChildThread* child_thread = ChildThread::Get())
child_thread->RecordComputedAction(name.Action()); child_thread->RecordComputedAction(name.Action());
@@ -757,11 +706,6 @@ bool BlinkPlatformImpl::IsLowEndDevice() {
return base::SysInfo::IsLowEndDevice(); return base::SysInfo::IsLowEndDevice();
} }
bool BlinkPlatformImpl::IsMainThread() const {
return main_thread_task_runner_.get() &&
main_thread_task_runner_->BelongsToCurrentThread();
}
WebString BlinkPlatformImpl::DomCodeStringFromEnum(int dom_code) { WebString BlinkPlatformImpl::DomCodeStringFromEnum(int dom_code) {
return WebString::FromUTF8(ui::KeycodeConverter::DomCodeToCodeString( return WebString::FromUTF8(ui::KeycodeConverter::DomCodeToCodeString(
static_cast<ui::DomCode>(dom_code))); static_cast<ui::DomCode>(dom_code)));

@@ -10,7 +10,6 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/threading/thread_local_storage.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "build/build_config.h" #include "build/build_config.h"
@@ -33,16 +32,6 @@
#include "content/child/webthemeengine_impl_android.h" #include "content/child/webthemeengine_impl_android.h"
#endif #endif
namespace base {
class WaitableEvent;
}
namespace blink {
namespace scheduler {
class WebThreadBase;
}
}
namespace content { namespace content {
class WebCryptoImpl; class WebCryptoImpl;
@@ -72,10 +61,6 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
size_t MaxDecodedImageBytes() override; size_t MaxDecodedImageBytes() override;
bool IsLowEndDevice() override; bool IsLowEndDevice() override;
std::unique_ptr<blink::WebThread> CreateThread(
const blink::WebThreadCreationParams& params) override;
std::unique_ptr<blink::WebThread> CreateWebAudioThread() override;
blink::WebThread* CurrentThread() override;
void RecordAction(const blink::UserMetricsAction&) override; void RecordAction(const blink::UserMetricsAction&) override;
blink::WebData GetDataResource(const char* name) override; blink::WebData GetDataResource(const char* name) override;
@@ -100,22 +85,14 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
int DomKeyEnumFromString(const blink::WebString& key_string) override; int DomKeyEnumFromString(const blink::WebString& key_string) override;
bool IsDomKeyForModifier(int dom_key) override; bool IsDomKeyForModifier(int dom_key) override;
void WaitUntilWebThreadTLSUpdate(blink::scheduler::WebThreadBase* thread);
scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() const override; scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() const override;
std::unique_ptr<NestedMessageLoopRunner> CreateNestedMessageLoopRunner() std::unique_ptr<NestedMessageLoopRunner> CreateNestedMessageLoopRunner()
const override; const override;
protected:
bool IsMainThread() const;
private: private:
void UpdateWebThreadTLS(blink::WebThread* thread, base::WaitableEvent* event);
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
WebThemeEngineImpl native_theme_engine_; WebThemeEngineImpl native_theme_engine_;
base::ThreadLocalStorage::Slot current_thread_slot_;
webcrypto::WebCryptoImpl web_crypto_; webcrypto::WebCryptoImpl web_crypto_;
media::WebMediaCapabilitiesClientImpl media_capabilities_client_; media::WebMediaCapabilitiesClientImpl media_capabilities_client_;
}; };

@@ -164,12 +164,6 @@ void PpapiBlinkPlatformImpl::Shutdown() {
#endif #endif
} }
blink::WebThread* PpapiBlinkPlatformImpl::CurrentThread() {
if (IsMainThread())
return main_thread_;
return BlinkPlatformImpl::CurrentThread();
}
blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() { blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() {
#if !defined(OS_ANDROID) && !defined(OS_WIN) #if !defined(OS_ANDROID) && !defined(OS_WIN)
return sandbox_support_.get(); return sandbox_support_.get();

@@ -29,7 +29,6 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
void Shutdown(); void Shutdown();
// BlinkPlatformImpl methods: // BlinkPlatformImpl methods:
blink::WebThread* CurrentThread() override;
blink::WebSandboxSupport* GetSandboxSupport() override; blink::WebSandboxSupport* GetSandboxSupport() override;
unsigned long long VisitedLinkHash(const char* canonical_url, unsigned long long VisitedLinkHash(const char* canonical_url,
size_t length) override; size_t length) override;

@@ -381,15 +381,12 @@ RendererBlinkPlatformImpl::CreateNetworkURLLoaderFactory() {
void RendererBlinkPlatformImpl::SetCompositorThread( void RendererBlinkPlatformImpl::SetCompositorThread(
blink::scheduler::WebThreadBase* compositor_thread) { blink::scheduler::WebThreadBase* compositor_thread) {
// TODO(yutak): Compositor thread is currently owned by RenderThreadImpl,
// but should probably be owned by Platform so this wouldn't depend on
// WebThread.
compositor_thread_ = compositor_thread; compositor_thread_ = compositor_thread;
if (compositor_thread_) if (compositor_thread_)
WaitUntilWebThreadTLSUpdate(compositor_thread_); RegisterExtraThreadToTLS(compositor_thread_);
}
blink::WebThread* RendererBlinkPlatformImpl::CurrentThread() {
if (main_thread_->IsCurrentThread())
return main_thread_.get();
return BlinkPlatformImpl::CurrentThread();
} }
blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() { blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() {

@@ -197,7 +197,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::WebString ConvertIDNToUnicode(const blink::WebString& host) override; blink::WebString ConvertIDNToUnicode(const blink::WebString& host) override;
service_manager::Connector* GetConnector() override; service_manager::Connector* GetConnector() override;
blink::InterfaceProvider* GetInterfaceProvider() override; blink::InterfaceProvider* GetInterfaceProvider() override;
blink::WebThread* CurrentThread() override;
blink::BlameContext* GetTopLevelBlameContext() override; blink::BlameContext* GetTopLevelBlameContext() override;
void RecordRappor(const char* metric, void RecordRappor(const char* metric,
const blink::WebString& sample) override; const blink::WebString& sample) override;

@@ -301,12 +301,6 @@ TestBlinkWebUnitTestSupport::GetURLLoaderMockFactory() {
return url_loader_factory_.get(); return url_loader_factory_.get();
} }
blink::WebThread* TestBlinkWebUnitTestSupport::CurrentThread() {
if (main_thread_->IsCurrentThread())
return main_thread_;
return BlinkPlatformImpl::CurrentThread();
}
bool TestBlinkWebUnitTestSupport::IsThreadedAnimationEnabled() { bool TestBlinkWebUnitTestSupport::IsThreadedAnimationEnabled() {
return threaded_animation_; return threaded_animation_;
} }

@@ -53,8 +53,6 @@ class TestBlinkWebUnitTestSupport : public BlinkPlatformImpl {
blink::WebURLLoaderMockFactory* GetURLLoaderMockFactory() override; blink::WebURLLoaderMockFactory* GetURLLoaderMockFactory() override;
blink::WebThread* CurrentThread() override;
bool IsThreadedAnimationEnabled() override; bool IsThreadedAnimationEnabled() override;
std::unique_ptr<blink::WebRTCCertificateGenerator> std::unique_ptr<blink::WebRTCCertificateGenerator>

@@ -424,20 +424,24 @@ class BLINK_PLATFORM_EXPORT Platform {
// Threads ------------------------------------------------------- // Threads -------------------------------------------------------
// Creates an embedder-defined thread. // Thread creation is no longer customizable in Platform. CreateThread()
virtual std::unique_ptr<WebThread> CreateThread( // always creates a new physical thread for Blink. Platform maintains
const WebThreadCreationParams&); // the thread-local storage containing each WebThread object, so that
// CurrentThread() could return the correct thread object.
//
// TODO(yutak): These non-virtual functions should be moved to somewhere
// else, because they no longer require embedder's implementation.
// Creates a new thread. This may be called from a non-main thread (e.g.
// nested Web workers).
std::unique_ptr<WebThread> CreateThread(const WebThreadCreationParams&);
// Creates a WebAudio-specific thread with the elevated priority. Do NOT use // Creates a WebAudio-specific thread with the elevated priority. Do NOT use
// for any other purpose. // for any other purpose.
virtual std::unique_ptr<WebThread> CreateWebAudioThread(); std::unique_ptr<WebThread> CreateWebAudioThread();
// Returns an interface to the current thread. // Returns an interface to the current thread.
// WebThread* CurrentThread();
// The default implementation only works on the main thread. If your
// application supports multi-thread, you *must* override this function
// as well as CreateThread().
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.
@@ -744,11 +748,16 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual bool IsTakingV8ContextSnapshot() { return false; } virtual bool IsTakingV8ContextSnapshot() { return false; }
protected: protected:
void RegisterExtraThreadToTLS(WebThread*);
WebThread* main_thread_; WebThread* main_thread_;
private: private:
static void InitializeCommon(Platform* platform); static void InitializeCommon(Platform* platform);
void WaitUntilWebThreadTLSUpdate(WebThread*);
void UpdateWebThreadTLS(WebThread* thread, base::WaitableEvent* event);
// Platform owns the main thread in most cases. The pointer value is the same // Platform owns the main thread in most cases. The pointer value is the same
// as main_thread_ if this variable is non-null. // as main_thread_ if this variable is non-null.
// //
@@ -756,6 +765,11 @@ class BLINK_PLATFORM_EXPORT Platform {
// overrides the old Platform. In this case, main_thread_ points to the old // overrides the old Platform. In this case, main_thread_ points to the old
// Platform's main thread. See testing_platform_support.h for this. // Platform's main thread. See testing_platform_support.h for this.
std::unique_ptr<WebThread> owned_main_thread_; std::unique_ptr<WebThread> owned_main_thread_;
// We can't use WTF stuff here. Ultimately these should go away (see comments
// near CreateThread()), though.
base::ThreadLocalStorage::Slot current_thread_slot_;
base::Lock create_thread_lock_;
}; };
} // namespace blink } // namespace blink

@@ -29,8 +29,10 @@ class BLINK_PLATFORM_EXPORT WebThreadBase : public WebThread {
public: public:
~WebThreadBase() override; ~WebThreadBase() override;
// CreateWorkerThread() may be called from a non-main thread.
static std::unique_ptr<WebThreadBase> CreateWorkerThread( static std::unique_ptr<WebThreadBase> CreateWorkerThread(
const WebThreadCreationParams& params); const WebThreadCreationParams& params);
static std::unique_ptr<WebThreadBase> CreateCompositorThread( static std::unique_ptr<WebThreadBase> CreateCompositorThread(
const WebThreadCreationParams& params); const WebThreadCreationParams& params);

@@ -28,7 +28,6 @@
#include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h" #include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/waitable_event.h" #include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/web_thread_supporting_gc.h" #include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
@@ -37,17 +36,6 @@
namespace blink { namespace blink {
namespace { namespace {
class AnimationWorkletTestPlatform : public TestingPlatformSupport {
public:
// Need to override the thread creating support so we can actually run
// Animation Worklet code that would go on a backing thread in non-test
// code. i.e. most tests remove the extra threads, but we need this one.
std::unique_ptr<WebThread> CreateThread(
const blink::WebThreadCreationParams& params) override {
return old_platform_->CreateThread(params);
}
};
class TestAnimationWorkletProxyClient : public AnimationWorkletProxyClient { class TestAnimationWorkletProxyClient : public AnimationWorkletProxyClient {
public: public:
TestAnimationWorkletProxyClient() TestAnimationWorkletProxyClient()
@@ -127,7 +115,6 @@ class AnimationWorkletThreadTest : public PageTestBase {
} }
std::unique_ptr<WorkerReportingProxy> reporting_proxy_; std::unique_ptr<WorkerReportingProxy> reporting_proxy_;
ScopedTestingPlatformSupport<AnimationWorkletTestPlatform> platform_;
}; };
TEST_F(AnimationWorkletThreadTest, Basic) { TEST_F(AnimationWorkletThreadTest, Basic) {

@@ -84,11 +84,6 @@ class AudioContextAutoplayTestPlatform : public TestingPlatformSupport {
AudioHardwareSampleRate(), AudioHardwareBufferSize()); AudioHardwareSampleRate(), AudioHardwareBufferSize());
} }
std::unique_ptr<WebThread> CreateThread(
const WebThreadCreationParams& params) override {
return old_platform_->CreateThread(params);
}
double AudioHardwareSampleRate() override { return 44100; } double AudioHardwareSampleRate() override { return 44100; }
size_t AudioHardwareBufferSize() override { return 128; } size_t AudioHardwareBufferSize() override { return 128; }
}; };

@@ -72,11 +72,6 @@ class AudioContextTestPlatform : public TestingPlatformSupport {
AudioHardwareSampleRate(), buffer_size); AudioHardwareSampleRate(), buffer_size);
} }
std::unique_ptr<WebThread> CreateThread(
const WebThreadCreationParams& params) override {
return old_platform_->CreateThread(params);
}
double AudioHardwareSampleRate() override { return 44100; } double AudioHardwareSampleRate() override { return 44100; }
size_t AudioHardwareBufferSize() override { return 128; } size_t AudioHardwareBufferSize() override { return 128; }
}; };

@@ -33,12 +33,14 @@
#include <memory> #include <memory>
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_manager.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/webmidi/web_midi_accessor.h" #include "third_party/blink/public/platform/modules/webmidi/web_midi_accessor.h"
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_canvas_capture_handler.h" #include "third_party/blink/public/platform/web_canvas_capture_handler.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
@@ -51,6 +53,7 @@
#include "third_party/blink/public/platform/web_storage_namespace.h" #include "third_party/blink/public/platform/web_storage_namespace.h"
#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h" #include "third_party/blink/public/platform/websocket_handshake_throttle.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/font_family_names.h" #include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h" #include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
@@ -170,6 +173,8 @@ void Platform::Initialize(
g_platform = platform; g_platform = platform;
g_platform->owned_main_thread_ = main_thread_scheduler->CreateMainThread(); g_platform->owned_main_thread_ = main_thread_scheduler->CreateMainThread();
g_platform->main_thread_ = g_platform->owned_main_thread_.get(); g_platform->main_thread_ = g_platform->owned_main_thread_.get();
DCHECK(!g_platform->current_thread_slot_.Get());
g_platform->current_thread_slot_.Set(g_platform->main_thread_);
InitializeCommon(platform); InitializeCommon(platform);
} }
@@ -179,6 +184,8 @@ void Platform::CreateMainThreadAndInitialize(Platform* platform) {
g_platform = platform; g_platform = platform;
g_platform->owned_main_thread_ = std::make_unique<SimpleMainThread>(); g_platform->owned_main_thread_ = std::make_unique<SimpleMainThread>();
g_platform->main_thread_ = g_platform->owned_main_thread_.get(); g_platform->main_thread_ = g_platform->owned_main_thread_.get();
DCHECK(!g_platform->current_thread_slot_.Get());
g_platform->current_thread_slot_.Set(g_platform->main_thread_);
InitializeCommon(platform); InitializeCommon(platform);
} }
@@ -240,6 +247,12 @@ void Platform::SetCurrentPlatformForTesting(Platform* platform) {
platform->main_thread_ = platform->owned_main_thread_.get(); platform->main_thread_ = platform->owned_main_thread_.get();
} }
// Set only the main thread to TLS for the new platform. This is OK for the
// testing purposes. The TLS slot may already be set when
// ScopedTestingPlatformSupport tries to revert to the old platform.
if (!platform->current_thread_slot_.Get())
platform->current_thread_slot_.Set(platform->main_thread_);
g_platform = platform; g_platform = platform;
} }
@@ -266,9 +279,7 @@ WebThread* Platform::MainThread() const {
} }
WebThread* Platform::CurrentThread() { WebThread* Platform::CurrentThread() {
DCHECK(main_thread_); return static_cast<WebThread*>(current_thread_slot_.Get());
DCHECK(WTF::IsMainThread());
return main_thread_;
} }
service_manager::Connector* Platform::GetConnector() { service_manager::Connector* Platform::GetConnector() {
@@ -296,11 +307,43 @@ std::unique_ptr<WebStorageNamespace> Platform::CreateSessionStorageNamespace(
std::unique_ptr<WebThread> Platform::CreateThread( std::unique_ptr<WebThread> Platform::CreateThread(
const WebThreadCreationParams& params) { const WebThreadCreationParams& params) {
return nullptr; std::unique_ptr<scheduler::WebThreadBase> thread =
scheduler::WebThreadBase::CreateWorkerThread(params);
thread->Init();
WaitUntilWebThreadTLSUpdate(thread.get());
return std::move(thread);
} }
std::unique_ptr<WebThread> Platform::CreateWebAudioThread() { std::unique_ptr<WebThread> Platform::CreateWebAudioThread() {
return nullptr; WebThreadCreationParams params(WebThreadType::kWebAudioThread);
// WebAudio uses a thread with |DISPLAY| priority to avoid glitch when the
// system is under the high pressure. Note that the main browser thread also
// runs with same priority. (see: crbug.com/734539)
params.thread_options.priority = base::ThreadPriority::DISPLAY;
return CreateThread(params);
}
void Platform::WaitUntilWebThreadTLSUpdate(WebThread* thread) {
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
// This cross-thread posting is guaranteed to be safe.
PostCrossThreadTask(*thread->GetTaskRunner(), FROM_HERE,
CrossThreadBind(&Platform::UpdateWebThreadTLS,
WTF::CrossThreadUnretained(this),
WTF::CrossThreadUnretained(thread),
WTF::CrossThreadUnretained(&event)));
event.Wait();
}
void Platform::UpdateWebThreadTLS(WebThread* thread,
base::WaitableEvent* event) {
DCHECK(!current_thread_slot_.Get());
current_thread_slot_.Set(thread);
event->Signal();
}
void Platform::RegisterExtraThreadToTLS(WebThread* thread) {
WaitUntilWebThreadTLSUpdate(thread);
} }
std::unique_ptr<WebGraphicsContext3DProvider> std::unique_ptr<WebGraphicsContext3DProvider>

@@ -108,10 +108,6 @@ WebString TestingPlatformSupport::DefaultLocale() {
return WebString::FromUTF8("en-US"); return WebString::FromUTF8("en-US");
} }
WebThread* TestingPlatformSupport::CurrentThread() {
return old_platform_ ? old_platform_->CurrentThread() : nullptr;
}
WebBlobRegistry* TestingPlatformSupport::GetBlobRegistry() { WebBlobRegistry* TestingPlatformSupport::GetBlobRegistry() {
return old_platform_ ? old_platform_->GetBlobRegistry() : nullptr; return old_platform_ ? old_platform_->GetBlobRegistry() : nullptr;
} }

@@ -48,7 +48,6 @@ class TestDiscardableMemoryAllocator;
} }
namespace blink { namespace blink {
class WebThread;
// A base class to override Platform methods for testing. You can override the // A base class to override Platform methods for testing. You can override the
// behavior by subclassing TestingPlatformSupport or using // behavior by subclassing TestingPlatformSupport or using
@@ -61,7 +60,6 @@ class TestingPlatformSupport : public Platform {
// Platform: // Platform:
WebString DefaultLocale() override; WebString DefaultLocale() override;
WebThread* CurrentThread() override;
WebBlobRegistry* GetBlobRegistry() override; WebBlobRegistry* GetBlobRegistry() override;
std::unique_ptr<WebIDBFactory> CreateIdbFactory() override; std::unique_ptr<WebIDBFactory> CreateIdbFactory() override;
WebURLLoaderMockFactory* GetURLLoaderMockFactory() override; WebURLLoaderMockFactory* GetURLLoaderMockFactory() override;

@@ -29,16 +29,16 @@ class ThreadWithCustomScheduler : public WebThread {
} // namespace } // namespace
TestingPlatformSupportWithCustomScheduler :: TestingPlatformSupportWithCustomScheduler::
TestingPlatformSupportWithCustomScheduler(ThreadScheduler* scheduler) TestingPlatformSupportWithCustomScheduler(ThreadScheduler* scheduler)
: thread_(std::make_unique<ThreadWithCustomScheduler>(scheduler)) {} : thread_(std::make_unique<ThreadWithCustomScheduler>(scheduler)) {
// If main_thread_ is set, Platform::SetCurrentPlatformForTesting() properly
TestingPlatformSupportWithCustomScheduler :: // sets up the platform so Platform::CurrentThread() would return the
~TestingPlatformSupportWithCustomScheduler() {} // thread specified here.
main_thread_ = thread_.get();
WebThread* TestingPlatformSupportWithCustomScheduler::CurrentThread() {
DCHECK(WTF::IsMainThread());
return thread_.get();
} }
TestingPlatformSupportWithCustomScheduler::
~TestingPlatformSupportWithCustomScheduler() {}
} // namespace blink } // namespace blink

@@ -26,8 +26,6 @@ class TestingPlatformSupportWithCustomScheduler
ThreadScheduler* scheduler); ThreadScheduler* scheduler);
~TestingPlatformSupportWithCustomScheduler() override; ~TestingPlatformSupportWithCustomScheduler() override;
WebThread* CurrentThread() override;
private: private:
std::unique_ptr<WebThread> thread_; std::unique_ptr<WebThread> thread_;

@@ -10,29 +10,10 @@
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h" #include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/waitable_event.h" #include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
namespace {
struct ThreadLocalStorage {
WebThread* current_thread = nullptr;
};
ThreadLocalStorage* GetThreadLocalStorage() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<ThreadLocalStorage>, tls, ());
return tls;
}
void PrepareCurrentThread(WaitableEvent* event, WebThread* thread) {
GetThreadLocalStorage()->current_thread = thread;
event->Signal();
}
} // namespace
TestingPlatformSupportWithMockScheduler:: TestingPlatformSupportWithMockScheduler::
TestingPlatformSupportWithMockScheduler() TestingPlatformSupportWithMockScheduler()
: test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>( : test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
@@ -47,6 +28,7 @@ TestingPlatformSupportWithMockScheduler::
scheduler_ = std::make_unique<scheduler::MainThreadSchedulerImpl>( scheduler_ = std::make_unique<scheduler::MainThreadSchedulerImpl>(
std::move(sequence_manager), base::nullopt); std::move(sequence_manager), base::nullopt);
thread_ = scheduler_->CreateMainThread(); thread_ = scheduler_->CreateMainThread();
main_thread_ = thread_.get();
// Set the work batch size to one so TakePendingTasks behaves as expected. // Set the work batch size to one so TakePendingTasks behaves as expected.
scheduler_->GetSchedulerHelperForTesting()->SetWorkBatchSizeForTesting(1); scheduler_->GetSchedulerHelperForTesting()->SetWorkBatchSizeForTesting(1);
@@ -59,31 +41,6 @@ TestingPlatformSupportWithMockScheduler::
scheduler_->Shutdown(); scheduler_->Shutdown();
} }
std::unique_ptr<WebThread>
TestingPlatformSupportWithMockScheduler::CreateThread(
const WebThreadCreationParams& params) {
std::unique_ptr<scheduler::WebThreadBase> thread =
scheduler::WebThreadBase::CreateWorkerThread(params);
thread->Init();
WaitableEvent event;
thread->GetTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(PrepareCurrentThread, base::Unretained(&event),
base::Unretained(thread.get())));
event.Wait();
return std::move(thread);
}
WebThread* TestingPlatformSupportWithMockScheduler::CurrentThread() {
DCHECK_EQ(thread_->IsCurrentThread(), IsMainThread());
if (thread_->IsCurrentThread()) {
return thread_.get();
}
ThreadLocalStorage* storage = GetThreadLocalStorage();
DCHECK(storage->current_thread);
return storage->current_thread;
}
void TestingPlatformSupportWithMockScheduler::RunSingleTask() { void TestingPlatformSupportWithMockScheduler::RunSingleTask() {
base::circular_deque<base::TestPendingTask> tasks = base::circular_deque<base::TestPendingTask> tasks =
test_task_runner_->TakePendingTasks(); test_task_runner_->TakePendingTasks();

@@ -35,11 +35,6 @@ class TestingPlatformSupportWithMockScheduler : public TestingPlatformSupport {
TestingPlatformSupportWithMockScheduler(); TestingPlatformSupportWithMockScheduler();
~TestingPlatformSupportWithMockScheduler() override; ~TestingPlatformSupportWithMockScheduler() override;
// Platform:
std::unique_ptr<WebThread> CreateThread(
const WebThreadCreationParams&) override;
WebThread* CurrentThread() override;
// Runs a single task. // Runs a single task.
void RunSingleTask(); void RunSingleTask();