Commit 5738043d authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Worker: Merge InProcessWorkerMessagingProxy into DedicatedWorkerMessagingProxy

This CL merges InProcessWorkerMessagingProxy into DedicatedWorkerMessagingProxy
because DedicatedWorkerMessagingProxy is the only subclass of the
InProcessWorkerMessagingProxy after CompositorWorkerMessagingProxy was
removed[1].

Before this CL:
  - ThreadedMessagingProxyBase
    - InProcessWorkerMessagingProxy
      - DedicatedWorkerMessagingProxy
      - (CompositorWorkerMessagingProxy)  <= Removed by the previous CL
    - ThreadedWorkletMessagingProxy
      - AnimationWorkletMessagingProxy
      - AudioWorkletMessagingProxy

After this CL:
  - ThreadedMessagingProxyBase
    - DedicatedWorkerMessagingProxy
    - ThreadedWorkletMessagingProxy
      - AnimationWorkletMessagingProxy
      - AudioWorkletMessagingProxy

[1] https://chromium-review.googlesource.com/c/chromium/src/+/673484

Bug: 769577
Change-Id: I011136db5f7951fe12cfb6f6d0c411b1027fb274
Reviewed-on: https://chromium-review.googlesource.com/688116
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505001}
parent 576ba67b
......@@ -11,7 +11,7 @@
#include "core/frame/LocalFrame.h"
#include "core/frame/WebLocalFrameImpl.h"
#include "core/leak_detector/BlinkLeakDetectorClient.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include "core/workers/DedicatedWorkerMessagingProxy.h"
#include "core/workers/WorkerThread.h"
#include "platform/Timer.h"
#include "platform/bindings/V8PerIsolateData.h"
......@@ -87,7 +87,7 @@ void BlinkLeakDetector::TimerFiredGC(TimerBase*) {
if (--number_of_gc_needed_ > 0) {
delayed_gc_timer_.StartOneShot(0, BLINK_FROM_HERE);
} else if (number_of_gc_needed_ > -1 &&
InProcessWorkerMessagingProxy::ProxyCount()) {
DedicatedWorkerMessagingProxy::ProxyCount()) {
// It is possible that all posted tasks for finalizing in-process proxy
// objects will not have run before the final round of GCs started. If so,
// do yet another pass, letting these tasks run and then afterwards perform
......
......@@ -18,8 +18,6 @@ blink_core_sources("workers") {
"GlobalScopeCreationParams.h",
"InProcessWorkerBase.cpp",
"InProcessWorkerBase.h",
"InProcessWorkerMessagingProxy.cpp",
"InProcessWorkerMessagingProxy.h",
"InProcessWorkerObjectProxy.cpp",
"InProcessWorkerObjectProxy.h",
"InstalledScriptsManager.cpp",
......
......@@ -4,21 +4,168 @@
#include "core/workers/DedicatedWorkerMessagingProxy.h"
#include <memory>
#include "bindings/core/v8/V8CacheOptions.h"
#include "core/dom/Document.h"
#include "core/dom/TaskRunnerHelper.h"
#include "core/events/ErrorEvent.h"
#include "core/events/MessageEvent.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "core/workers/DedicatedWorkerThread.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/InProcessWorkerBase.h"
#include "core/workers/InProcessWorkerObjectProxy.h"
#include "core/workers/WorkerClients.h"
#include <memory>
#include "core/workers/WorkerInspectorProxy.h"
#include "platform/CrossThreadFunctional.h"
#include "platform/WebTaskRunner.h"
#include "platform/wtf/WTF.h"
namespace blink {
struct DedicatedWorkerMessagingProxy::QueuedTask {
RefPtr<SerializedScriptValue> message;
MessagePortChannelArray channels;
};
DedicatedWorkerMessagingProxy::DedicatedWorkerMessagingProxy(
ExecutionContext* execution_context,
InProcessWorkerBase* worker_object,
WorkerClients* worker_clients)
: InProcessWorkerMessagingProxy(worker_object, worker_clients) {}
: ThreadedMessagingProxyBase(execution_context, worker_clients),
worker_object_(worker_object) {
worker_object_proxy_ =
InProcessWorkerObjectProxy::Create(this, GetParentFrameTaskRunners());
}
DedicatedWorkerMessagingProxy::~DedicatedWorkerMessagingProxy() = default;
void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
const KURL& script_url,
const String& user_agent,
const String& source_code,
const String& referrer_policy) {
DCHECK(IsParentContextThread());
if (AskedToTerminate()) {
// Worker.terminate() could be called from JS before the thread was
// created.
return;
}
Document* document = ToDocument(GetExecutionContext());
SecurityOrigin* starter_origin = document->GetSecurityOrigin();
DedicatedWorkerMessagingProxy::~DedicatedWorkerMessagingProxy() {}
ContentSecurityPolicy* csp = document->GetContentSecurityPolicy();
DCHECK(csp);
WorkerThreadStartMode start_mode =
GetWorkerInspectorProxy()->WorkerStartMode(document);
std::unique_ptr<WorkerSettings> worker_settings =
WTF::WrapUnique(new WorkerSettings(document->GetSettings()));
auto global_scope_creation_params =
WTF::MakeUnique<GlobalScopeCreationParams>(
script_url, user_agent, source_code, nullptr, start_mode,
csp->Headers().get(), referrer_policy, starter_origin,
ReleaseWorkerClients(), document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
std::move(worker_settings), kV8CacheOptionsDefault);
InitializeWorkerThread(std::move(global_scope_creation_params),
CreateBackingThreadStartupData(ToIsolate(document)),
script_url);
}
void DedicatedWorkerMessagingProxy::PostMessageToWorkerGlobalScope(
RefPtr<SerializedScriptValue> message,
MessagePortChannelArray channels) {
DCHECK(IsParentContextThread());
if (AskedToTerminate())
return;
if (GetWorkerThread()) {
WTF::CrossThreadClosure task = CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessMessageFromWorkerObject,
CrossThreadUnretained(&WorkerObjectProxy()), std::move(message),
WTF::Passed(std::move(channels)),
CrossThreadUnretained(GetWorkerThread()));
TaskRunnerHelper::Get(TaskType::kPostedMessage, GetWorkerThread())
->PostTask(BLINK_FROM_HERE, std::move(task));
} else {
queued_early_tasks_.push_back(
QueuedTask{std::move(message), std::move(channels)});
}
}
void DedicatedWorkerMessagingProxy::WorkerThreadCreated() {
DCHECK(IsParentContextThread());
ThreadedMessagingProxyBase::WorkerThreadCreated();
for (auto& queued_task : queued_early_tasks_) {
WTF::CrossThreadClosure task = CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessMessageFromWorkerObject,
CrossThreadUnretained(&WorkerObjectProxy()),
std::move(queued_task.message),
WTF::Passed(std::move(queued_task.channels)),
CrossThreadUnretained(GetWorkerThread()));
TaskRunnerHelper::Get(TaskType::kPostedMessage, GetWorkerThread())
->PostTask(BLINK_FROM_HERE, std::move(task));
}
queued_early_tasks_.clear();
}
bool DedicatedWorkerMessagingProxy::HasPendingActivity() const {
DCHECK(IsParentContextThread());
return !AskedToTerminate();
}
void DedicatedWorkerMessagingProxy::PostMessageToWorkerObject(
RefPtr<SerializedScriptValue> message,
MessagePortChannelArray channels) {
DCHECK(IsParentContextThread());
if (!worker_object_ || AskedToTerminate())
return;
MessagePortArray* ports =
MessagePort::EntanglePorts(*GetExecutionContext(), std::move(channels));
worker_object_->DispatchEvent(
MessageEvent::Create(ports, std::move(message)));
}
void DedicatedWorkerMessagingProxy::DispatchErrorEvent(
const String& error_message,
std::unique_ptr<SourceLocation> location,
int exception_id) {
DCHECK(IsParentContextThread());
if (!worker_object_)
return;
// We don't bother checking the askedToTerminate() flag here, because
// exceptions should *always* be reported even if the thread is terminated.
// This is intentionally different than the behavior in MessageWorkerTask,
// because terminated workers no longer deliver messages (section 4.6 of the
// WebWorker spec), but they do report exceptions.
ErrorEvent* event =
ErrorEvent::Create(error_message, location->Clone(), nullptr);
if (worker_object_->DispatchEvent(event) != DispatchEventResult::kNotCanceled)
return;
// The HTML spec requires to queue an error event using the DOM manipulation
// task source.
// https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2
TaskRunnerHelper::Get(TaskType::kDOMManipulation, GetWorkerThread())
->PostTask(BLINK_FROM_HERE,
CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessUnhandledException,
CrossThreadUnretained(worker_object_proxy_.get()),
exception_id, CrossThreadUnretained(GetWorkerThread())));
}
bool DedicatedWorkerMessagingProxy::IsAtomicsWaitAllowed() {
return true;
DEFINE_TRACE(DedicatedWorkerMessagingProxy) {
visitor->Trace(worker_object_);
ThreadedMessagingProxyBase::Trace(visitor);
}
WTF::Optional<WorkerBackingThreadStartupData>
......@@ -30,8 +177,7 @@ DedicatedWorkerMessagingProxy::CreateBackingThreadStartupData(
isolate->IsHeapLimitIncreasedForDebugging()
? HeapLimitMode::kIncreasedForDebugging
: HeapLimitMode::kDefault,
IsAtomicsWaitAllowed() ? AtomicsWaitMode::kAllow
: AtomicsWaitMode::kDisallow);
AtomicsWaitMode::kAllow);
}
std::unique_ptr<WorkerThread>
......
......@@ -5,27 +5,83 @@
#ifndef DedicatedWorkerMessagingProxy_h
#define DedicatedWorkerMessagingProxy_h
#include "core/CoreExport.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include <memory>
#include "core/CoreExport.h"
#include "core/dom/MessagePort.h"
#include "core/workers/ThreadedMessagingProxyBase.h"
#include "core/workers/WorkerBackingThreadStartupData.h"
#include "platform/heap/Handle.h"
#include "platform/wtf/Noncopyable.h"
#include "platform/wtf/Optional.h"
#include "platform/wtf/RefPtr.h"
namespace blink {
class CORE_EXPORT DedicatedWorkerMessagingProxy final
: public InProcessWorkerMessagingProxy {
class InProcessWorkerBase;
class InProcessWorkerObjectProxy;
class SerializedScriptValue;
class WorkerClients;
// TODO(nhiroki): Add the class-level comment once
// InProcessWorker->DedicatedWorker move is done (https://crbug.com/688116).
class CORE_EXPORT DedicatedWorkerMessagingProxy
: public ThreadedMessagingProxyBase {
WTF_MAKE_NONCOPYABLE(DedicatedWorkerMessagingProxy);
public:
DedicatedWorkerMessagingProxy(InProcessWorkerBase*, WorkerClients*);
DedicatedWorkerMessagingProxy(ExecutionContext*,
InProcessWorkerBase*,
WorkerClients*);
~DedicatedWorkerMessagingProxy() override;
bool IsAtomicsWaitAllowed() override;
// These methods should only be used on the parent context thread.
void StartWorkerGlobalScope(const KURL& script_url,
const String& user_agent,
const String& source_code,
const String& referrer_policy);
void PostMessageToWorkerGlobalScope(RefPtr<SerializedScriptValue>,
MessagePortChannelArray);
// Implements ThreadedMessagingProxyBase.
void WorkerThreadCreated() override;
bool HasPendingActivity() const;
// These methods come from worker context thread via
// InProcessWorkerObjectProxy and are called on the parent context thread.
void PostMessageToWorkerObject(RefPtr<SerializedScriptValue>,
MessagePortChannelArray);
void DispatchErrorEvent(const String& error_message,
std::unique_ptr<SourceLocation>,
int exception_id);
InProcessWorkerObjectProxy& WorkerObjectProxy() {
return *worker_object_proxy_.get();
}
DECLARE_VIRTUAL_TRACE();
private:
friend class DedicatedWorkerMessagingProxyForTest;
WTF::Optional<WorkerBackingThreadStartupData> CreateBackingThreadStartupData(
v8::Isolate*) override;
v8::Isolate*);
std::unique_ptr<WorkerThread> CreateWorkerThread() override;
std::unique_ptr<InProcessWorkerObjectProxy> worker_object_proxy_;
// This must be weak. The base class (i.e., ThreadedMessagingProxyBase) has a
// strong persistent reference to itself via SelfKeepAlive (see class-level
// comments on ThreadedMessagingProxyBase.h for details). To cut the
// persistent reference, this worker object needs to call a cleanup function
// in its dtor. If this is a strong reference, the dtor is never called
// because the worker object is reachable from the persistent reference.
WeakMember<InProcessWorkerBase> worker_object_;
// Tasks are queued here until there's a thread object created.
struct QueuedTask;
Vector<QueuedTask> queued_early_tasks_;
};
} // namespace blink
......
......@@ -9,9 +9,9 @@
#include "core/inspector/ConsoleMessageStorage.h"
#include "core/testing/DummyPageHolder.h"
#include "core/workers/DedicatedWorkerGlobalScope.h"
#include "core/workers/DedicatedWorkerMessagingProxy.h"
#include "core/workers/DedicatedWorkerThread.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include "core/workers/InProcessWorkerObjectProxy.h"
#include "core/workers/WorkerBackingThreadStartupData.h"
#include "core/workers/WorkerInspectorProxy.h"
......@@ -79,11 +79,10 @@ class InProcessWorkerObjectProxyForTest final
: public InProcessWorkerObjectProxy {
public:
InProcessWorkerObjectProxyForTest(
InProcessWorkerMessagingProxy* messaging_proxy,
DedicatedWorkerMessagingProxy* messaging_proxy,
ParentFrameTaskRunners* parent_frame_task_runners)
: InProcessWorkerObjectProxy(messaging_proxy, parent_frame_task_runners),
reported_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {
}
reported_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {}
void CountFeature(WebFeature feature) override {
// Any feature should be reported only one time.
......@@ -103,19 +102,18 @@ class InProcessWorkerObjectProxyForTest final
BitVector reported_features_;
};
class InProcessWorkerMessagingProxyForTest
: public InProcessWorkerMessagingProxy {
class DedicatedWorkerMessagingProxyForTest
: public DedicatedWorkerMessagingProxy {
public:
InProcessWorkerMessagingProxyForTest(ExecutionContext* execution_context)
: InProcessWorkerMessagingProxy(execution_context,
DedicatedWorkerMessagingProxyForTest(ExecutionContext* execution_context)
: DedicatedWorkerMessagingProxy(execution_context,
nullptr /* workerObject */,
nullptr /* workerClients */) {
worker_object_proxy_ = WTF::MakeUnique<InProcessWorkerObjectProxyForTest>(
this, GetParentFrameTaskRunners());
}
~InProcessWorkerMessagingProxyForTest() override {
}
~DedicatedWorkerMessagingProxyForTest() override = default;
void StartWithSourceCode(const String& source) {
KURL script_url(kParsedURLString, "http://fake.url/");
......@@ -133,7 +131,10 @@ class InProcessWorkerMessagingProxyForTest
nullptr /* workerClients */, kWebAddressSpaceLocal,
nullptr /* originTrialTokens */, nullptr /* workerSettings */,
kV8CacheOptionsDefault),
CreateBackingThreadStartupData(nullptr /* isolate */), script_url);
WorkerBackingThreadStartupData(
WorkerBackingThreadStartupData::HeapLimitMode::kDefault,
WorkerBackingThreadStartupData::AtomicsWaitMode::kAllow),
script_url);
}
DedicatedWorkerThreadForTest* GetDedicatedWorkerThread() {
......@@ -142,7 +143,7 @@ class InProcessWorkerMessagingProxyForTest
DEFINE_INLINE_VIRTUAL_TRACE() {
visitor->Trace(mock_worker_thread_lifecycle_observer_);
InProcessWorkerMessagingProxy::Trace(visitor);
DedicatedWorkerMessagingProxy::Trace(visitor);
}
private:
......@@ -158,13 +159,6 @@ class InProcessWorkerMessagingProxyForTest
return std::move(worker_thread);
}
WTF::Optional<WorkerBackingThreadStartupData> CreateBackingThreadStartupData(
v8::Isolate*) override {
return WorkerBackingThreadStartupData(
WorkerBackingThreadStartupData::HeapLimitMode::kDefault,
WorkerBackingThreadStartupData::AtomicsWaitMode::kAllow);
}
Member<MockWorkerThreadLifecycleObserver>
mock_worker_thread_lifecycle_observer_;
RefPtr<SecurityOrigin> security_origin_;
......@@ -177,7 +171,7 @@ class DedicatedWorkerTest : public ::testing::Test {
void SetUp() override {
page_ = DummyPageHolder::Create();
worker_messaging_proxy_ =
new InProcessWorkerMessagingProxyForTest(&page_->GetDocument());
new DedicatedWorkerMessagingProxyForTest(&page_->GetDocument());
}
void TearDown() override {
......@@ -190,7 +184,7 @@ class DedicatedWorkerTest : public ::testing::Test {
nullptr /* message */, MessagePortChannelArray());
}
InProcessWorkerMessagingProxyForTest* WorkerMessagingProxy() {
DedicatedWorkerMessagingProxyForTest* WorkerMessagingProxy() {
return worker_messaging_proxy_.Get();
}
......@@ -202,7 +196,7 @@ class DedicatedWorkerTest : public ::testing::Test {
private:
std::unique_ptr<DummyPageHolder> page_;
Persistent<InProcessWorkerMessagingProxyForTest> worker_messaging_proxy_;
Persistent<DedicatedWorkerMessagingProxyForTest> worker_messaging_proxy_;
};
TEST_F(DedicatedWorkerTest, PendingActivity_NoActivityAfterContextDestroyed) {
......
......@@ -9,7 +9,7 @@
#include "core/dom/ExecutionContext.h"
#include "core/events/MessageEvent.h"
#include "core/probe/CoreProbes.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include "core/workers/DedicatedWorkerMessagingProxy.h"
#include "core/workers/WorkerScriptLoader.h"
#include "platform/bindings/ScriptState.h"
#include "platform/loader/fetch/ResourceFetcher.h"
......@@ -67,7 +67,7 @@ bool InProcessWorkerBase::Initialize(ExecutionContext* context,
WTF::Bind(&InProcessWorkerBase::OnResponse, WrapPersistent(this)),
WTF::Bind(&InProcessWorkerBase::OnFinished, WrapPersistent(this)));
context_proxy_ = CreateInProcessWorkerMessagingProxy(context);
context_proxy_ = CreateMessagingProxy(context);
return true;
}
......
......@@ -17,9 +17,9 @@
namespace blink {
class DedicatedWorkerMessagingProxy;
class ExceptionState;
class ExecutionContext;
class InProcessWorkerMessagingProxy;
class ScriptState;
class WorkerScriptLoader;
......@@ -60,7 +60,7 @@ class CORE_EXPORT InProcessWorkerBase
// InProcessWorkerBase does not take ownership of the created proxy. The proxy
// is expected to manage its own lifetime, and delete itself in response to
// terminateWorkerGlobalScope().
virtual InProcessWorkerMessagingProxy* CreateInProcessWorkerMessagingProxy(
virtual DedicatedWorkerMessagingProxy* CreateMessagingProxy(
ExecutionContext*) = 0;
private:
......@@ -70,7 +70,7 @@ class CORE_EXPORT InProcessWorkerBase
RefPtr<WorkerScriptLoader> script_loader_;
Member<InProcessWorkerMessagingProxy> context_proxy_;
Member<DedicatedWorkerMessagingProxy> context_proxy_;
};
} // namespace blink
......
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include <memory>
#include "bindings/core/v8/V8CacheOptions.h"
#include "core/dom/Document.h"
#include "core/dom/SecurityContext.h"
#include "core/dom/TaskRunnerHelper.h"
#include "core/events/ErrorEvent.h"
#include "core/events/MessageEvent.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/loader/DocumentLoadTiming.h"
#include "core/loader/DocumentLoader.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/InProcessWorkerBase.h"
#include "core/workers/InProcessWorkerObjectProxy.h"
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerInspectorProxy.h"
#include "platform/CrossThreadFunctional.h"
#include "platform/WebTaskRunner.h"
#include "platform/wtf/WTF.h"
namespace blink {
struct InProcessWorkerMessagingProxy::QueuedTask {
RefPtr<SerializedScriptValue> message;
MessagePortChannelArray channels;
};
InProcessWorkerMessagingProxy::InProcessWorkerMessagingProxy(
InProcessWorkerBase* worker_object,
WorkerClients* worker_clients)
: InProcessWorkerMessagingProxy(worker_object->GetExecutionContext(),
worker_object,
worker_clients) {
DCHECK(worker_object_);
}
InProcessWorkerMessagingProxy::InProcessWorkerMessagingProxy(
ExecutionContext* execution_context,
InProcessWorkerBase* worker_object,
WorkerClients* worker_clients)
: ThreadedMessagingProxyBase(execution_context, worker_clients),
worker_object_(worker_object) {
worker_object_proxy_ =
InProcessWorkerObjectProxy::Create(this, GetParentFrameTaskRunners());
}
InProcessWorkerMessagingProxy::~InProcessWorkerMessagingProxy() = default;
void InProcessWorkerMessagingProxy::StartWorkerGlobalScope(
const KURL& script_url,
const String& user_agent,
const String& source_code,
const String& referrer_policy) {
DCHECK(IsParentContextThread());
if (AskedToTerminate()) {
// Worker.terminate() could be called from JS before the thread was
// created.
return;
}
Document* document = ToDocument(GetExecutionContext());
SecurityOrigin* starter_origin = document->GetSecurityOrigin();
ContentSecurityPolicy* csp = document->GetContentSecurityPolicy();
DCHECK(csp);
WorkerThreadStartMode start_mode =
GetWorkerInspectorProxy()->WorkerStartMode(document);
std::unique_ptr<WorkerSettings> worker_settings =
WTF::WrapUnique(new WorkerSettings(document->GetSettings()));
auto global_scope_creation_params =
WTF::MakeUnique<GlobalScopeCreationParams>(
script_url, user_agent, source_code, nullptr, start_mode,
csp->Headers().get(), referrer_policy, starter_origin,
ReleaseWorkerClients(), document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
std::move(worker_settings), kV8CacheOptionsDefault);
InitializeWorkerThread(std::move(global_scope_creation_params),
CreateBackingThreadStartupData(ToIsolate(document)),
script_url);
}
void InProcessWorkerMessagingProxy::PostMessageToWorkerObject(
RefPtr<SerializedScriptValue> message,
MessagePortChannelArray channels) {
DCHECK(IsParentContextThread());
if (!worker_object_ || AskedToTerminate())
return;
MessagePortArray* ports =
MessagePort::EntanglePorts(*GetExecutionContext(), std::move(channels));
worker_object_->DispatchEvent(
MessageEvent::Create(ports, std::move(message)));
}
void InProcessWorkerMessagingProxy::PostMessageToWorkerGlobalScope(
RefPtr<SerializedScriptValue> message,
MessagePortChannelArray channels) {
DCHECK(IsParentContextThread());
if (AskedToTerminate())
return;
if (GetWorkerThread()) {
WTF::CrossThreadClosure task = CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessMessageFromWorkerObject,
CrossThreadUnretained(&WorkerObjectProxy()), std::move(message),
WTF::Passed(std::move(channels)),
CrossThreadUnretained(GetWorkerThread()));
TaskRunnerHelper::Get(TaskType::kPostedMessage, GetWorkerThread())
->PostTask(BLINK_FROM_HERE, std::move(task));
} else {
queued_early_tasks_.push_back(
QueuedTask{std::move(message), std::move(channels)});
}
}
void InProcessWorkerMessagingProxy::DispatchErrorEvent(
const String& error_message,
std::unique_ptr<SourceLocation> location,
int exception_id) {
DCHECK(IsParentContextThread());
if (!worker_object_)
return;
// We don't bother checking the askedToTerminate() flag here, because
// exceptions should *always* be reported even if the thread is terminated.
// This is intentionally different than the behavior in MessageWorkerTask,
// because terminated workers no longer deliver messages (section 4.6 of the
// WebWorker spec), but they do report exceptions.
ErrorEvent* event =
ErrorEvent::Create(error_message, location->Clone(), nullptr);
if (worker_object_->DispatchEvent(event) != DispatchEventResult::kNotCanceled)
return;
// The HTML spec requires to queue an error event using the DOM manipulation
// task source.
// https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2
TaskRunnerHelper::Get(TaskType::kDOMManipulation, GetWorkerThread())
->PostTask(BLINK_FROM_HERE,
CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessUnhandledException,
CrossThreadUnretained(worker_object_proxy_.get()),
exception_id, CrossThreadUnretained(GetWorkerThread())));
}
void InProcessWorkerMessagingProxy::WorkerThreadCreated() {
DCHECK(IsParentContextThread());
ThreadedMessagingProxyBase::WorkerThreadCreated();
for (auto& queued_task : queued_early_tasks_) {
WTF::CrossThreadClosure task = CrossThreadBind(
&InProcessWorkerObjectProxy::ProcessMessageFromWorkerObject,
CrossThreadUnretained(&WorkerObjectProxy()),
std::move(queued_task.message),
WTF::Passed(std::move(queued_task.channels)),
CrossThreadUnretained(GetWorkerThread()));
TaskRunnerHelper::Get(TaskType::kPostedMessage, GetWorkerThread())
->PostTask(BLINK_FROM_HERE, std::move(task));
}
queued_early_tasks_.clear();
}
DEFINE_TRACE(InProcessWorkerMessagingProxy) {
visitor->Trace(worker_object_);
ThreadedMessagingProxyBase::Trace(visitor);
}
bool InProcessWorkerMessagingProxy::HasPendingActivity() const {
DCHECK(IsParentContextThread());
return !AskedToTerminate();
}
} // namespace blink
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef InProcessWorkerMessagingProxy_h
#define InProcessWorkerMessagingProxy_h
#include <memory>
#include "core/CoreExport.h"
#include "core/dom/ExecutionContext.h"
#include "core/dom/MessagePort.h"
#include "core/workers/ThreadedMessagingProxyBase.h"
#include "core/workers/WorkerBackingThreadStartupData.h"
#include "platform/heap/Handle.h"
#include "platform/wtf/Noncopyable.h"
#include "platform/wtf/Optional.h"
#include "platform/wtf/RefPtr.h"
namespace blink {
class ExecutionContext;
class InProcessWorkerBase;
class InProcessWorkerObjectProxy;
class SerializedScriptValue;
class WorkerClients;
class CORE_EXPORT InProcessWorkerMessagingProxy
: public ThreadedMessagingProxyBase {
WTF_MAKE_NONCOPYABLE(InProcessWorkerMessagingProxy);
public:
// These methods should only be used on the parent context thread.
void StartWorkerGlobalScope(const KURL& script_url,
const String& user_agent,
const String& source_code,
const String& referrer_policy);
void PostMessageToWorkerGlobalScope(RefPtr<SerializedScriptValue>,
MessagePortChannelArray);
// Implements ThreadedMessagingProxyBase.
void WorkerThreadCreated() override;
bool HasPendingActivity() const;
// These methods come from worker context thread via
// InProcessWorkerObjectProxy and are called on the parent context thread.
void PostMessageToWorkerObject(RefPtr<SerializedScriptValue>,
MessagePortChannelArray);
void DispatchErrorEvent(const String& error_message,
std::unique_ptr<SourceLocation>,
int exception_id);
DECLARE_VIRTUAL_TRACE();
protected:
InProcessWorkerMessagingProxy(InProcessWorkerBase*, WorkerClients*);
~InProcessWorkerMessagingProxy() override;
InProcessWorkerObjectProxy& WorkerObjectProxy() {
return *worker_object_proxy_.get();
}
// Whether Atomics.wait (a blocking function call) is allowed on this thread.
virtual bool IsAtomicsWaitAllowed() { return false; }
private:
friend class InProcessWorkerMessagingProxyForTest;
InProcessWorkerMessagingProxy(ExecutionContext*,
InProcessWorkerBase*,
WorkerClients*);
// TODO(nhiroki): Remove this creation function once we no longer have
// CompositorWorker.
virtual WTF::Optional<WorkerBackingThreadStartupData>
CreateBackingThreadStartupData(v8::Isolate*) = 0;
std::unique_ptr<InProcessWorkerObjectProxy> worker_object_proxy_;
// This must be weak. The base class (i.e., ThreadedMessagingProxyBase) has a
// strong persistent reference to itself via SelfKeepAlive (see class-level
// comments on ThreadedMessagingProxyBase.h for details). To cut the
// persistent reference, this worker object needs to call a cleanup function
// in its dtor. If this is a strong reference, the dtor is never called
// because the worker object is reachable from the persistent reference.
WeakMember<InProcessWorkerBase> worker_object_;
// Tasks are queued here until there's a thread object created.
struct QueuedTask;
Vector<QueuedTask> queued_early_tasks_;
};
} // namespace blink
#endif // InProcessWorkerMessagingProxy_h
......@@ -38,7 +38,7 @@
#include "core/dom/TaskRunnerHelper.h"
#include "core/events/MessageEvent.h"
#include "core/inspector/ConsoleMessage.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include "core/workers/DedicatedWorkerMessagingProxy.h"
#include "core/workers/ParentFrameTaskRunners.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerThread.h"
......@@ -51,7 +51,7 @@
namespace blink {
std::unique_ptr<InProcessWorkerObjectProxy> InProcessWorkerObjectProxy::Create(
InProcessWorkerMessagingProxy* messaging_proxy_weak_ptr,
DedicatedWorkerMessagingProxy* messaging_proxy_weak_ptr,
ParentFrameTaskRunners* parent_frame_task_runners) {
DCHECK(messaging_proxy_weak_ptr);
return WTF::WrapUnique(new InProcessWorkerObjectProxy(
......@@ -67,7 +67,7 @@ void InProcessWorkerObjectProxy::PostMessageToWorkerObject(
->Get(TaskType::kPostedMessage)
->PostTask(BLINK_FROM_HERE,
CrossThreadBind(
&InProcessWorkerMessagingProxy::PostMessageToWorkerObject,
&DedicatedWorkerMessagingProxy::PostMessageToWorkerObject,
messaging_proxy_weak_ptr_, std::move(message),
WTF::Passed(std::move(channels))));
}
......@@ -99,7 +99,7 @@ void InProcessWorkerObjectProxy::ReportException(
->Get(TaskType::kUnspecedTimer)
->PostTask(
BLINK_FROM_HERE,
CrossThreadBind(&InProcessWorkerMessagingProxy::DispatchErrorEvent,
CrossThreadBind(&DedicatedWorkerMessagingProxy::DispatchErrorEvent,
messaging_proxy_weak_ptr_, error_message,
WTF::Passed(location->Clone()), exception_id));
}
......@@ -115,7 +115,7 @@ void InProcessWorkerObjectProxy::WillDestroyWorkerGlobalScope() {
}
InProcessWorkerObjectProxy::InProcessWorkerObjectProxy(
InProcessWorkerMessagingProxy* messaging_proxy_weak_ptr,
DedicatedWorkerMessagingProxy* messaging_proxy_weak_ptr,
ParentFrameTaskRunners* parent_frame_task_runners)
: ThreadedObjectProxyBase(parent_frame_task_runners),
messaging_proxy_weak_ptr_(messaging_proxy_weak_ptr) {}
......
......@@ -42,7 +42,7 @@
namespace blink {
class InProcessWorkerMessagingProxy;
class DedicatedWorkerMessagingProxy;
class ParentFrameTaskRunners;
class ThreadedMessagingProxyBase;
class WorkerGlobalScope;
......@@ -60,7 +60,7 @@ class CORE_EXPORT InProcessWorkerObjectProxy : public ThreadedObjectProxyBase {
public:
static std::unique_ptr<InProcessWorkerObjectProxy> Create(
InProcessWorkerMessagingProxy*,
DedicatedWorkerMessagingProxy*,
ParentFrameTaskRunners*);
~InProcessWorkerObjectProxy() override;
......@@ -79,7 +79,7 @@ class CORE_EXPORT InProcessWorkerObjectProxy : public ThreadedObjectProxyBase {
void WillDestroyWorkerGlobalScope() override;
protected:
InProcessWorkerObjectProxy(InProcessWorkerMessagingProxy*,
InProcessWorkerObjectProxy(DedicatedWorkerMessagingProxy*,
ParentFrameTaskRunners*);
CrossThreadWeakPersistent<ThreadedMessagingProxyBase> MessagingProxyWeakPtr()
......@@ -89,9 +89,9 @@ class CORE_EXPORT InProcessWorkerObjectProxy : public ThreadedObjectProxyBase {
friend class InProcessWorkerObjectProxyForTest;
// No guarantees about the lifetimes of tasks posted by this proxy wrt the
// InProcessWorkerMessagingProxy so a weak pointer must be used when posting
// DedicatedWorkerMessagingProxy so a weak pointer must be used when posting
// the tasks.
CrossThreadWeakPersistent<InProcessWorkerMessagingProxy>
CrossThreadWeakPersistent<DedicatedWorkerMessagingProxy>
messaging_proxy_weak_ptr_;
CrossThreadPersistent<WorkerGlobalScope> worker_global_scope_;
......
......@@ -44,7 +44,7 @@ const AtomicString& Worker::InterfaceName() const {
return EventTargetNames::Worker;
}
InProcessWorkerMessagingProxy* Worker::CreateInProcessWorkerMessagingProxy(
DedicatedWorkerMessagingProxy* Worker::CreateMessagingProxy(
ExecutionContext* context) {
Document* document = ToDocument(context);
WebLocalFrameImpl* web_frame =
......@@ -57,7 +57,7 @@ InProcessWorkerMessagingProxy* Worker::CreateInProcessWorkerMessagingProxy(
*worker_clients);
ProvideContentSettingsClientToWorker(
worker_clients, web_frame->Client()->CreateWorkerContentSettingsClient());
return new DedicatedWorkerMessagingProxy(this, worker_clients);
return new DedicatedWorkerMessagingProxy(context, this, worker_clients);
}
} // namespace blink
......@@ -11,9 +11,9 @@
namespace blink {
class DedicatedWorkerMessagingProxy;
class ExceptionState;
class ExecutionContext;
class InProcessWorkerMessagingProxy;
class CORE_EXPORT Worker final : public InProcessWorkerBase {
DEFINE_WRAPPERTYPEINFO();
......@@ -26,7 +26,7 @@ class CORE_EXPORT Worker final : public InProcessWorkerBase {
protected:
explicit Worker(ExecutionContext*);
InProcessWorkerMessagingProxy* CreateInProcessWorkerMessagingProxy(
DedicatedWorkerMessagingProxy* CreateMessagingProxy(
ExecutionContext*) override;
const AtomicString& InterfaceName() const override;
};
......
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