Commit 322942d0 authored by nhiroki's avatar nhiroki Committed by Commit bot

Worklet: Introduce "pending tasks struct" concept defined in the Worklet spec

This is split from https://codereview.chromium.org/2840523002/

This CL introduces "pending tasks struct" concept defined in the Worklet spec:
https://drafts.css-houdini.org/worklets/#pending-tasks-struct

The pending tasks struct is used as a kind of barrier closure: when
Worklet::addModule() is called, multiple WorkletGlobalScopes associated with the
Worklet may start module loading. The struct waits until they all are completed
and then resolves a promise. If one of them is failed, the struct immediately
rejects a promise and ignores following completions.

This CL also removes WorkletObjectProxy and the request id mechanism in
MainThreadWorklet using the pending tasks struct.

BUG=627945

Review-Url: https://codereview.chromium.org/2839123003
Cr-Commit-Position: refs/heads/master@{#467908}
parent fca892fe
...@@ -54,9 +54,6 @@ class WorkletScriptLoader final ...@@ -54,9 +54,6 @@ class WorkletScriptLoader final
// after Client::notifyWorkletScriptLoadingFinished() is called. // after Client::notifyWorkletScriptLoadingFinished() is called.
bool WasScriptLoadSuccessful() const; bool WasScriptLoadSuccessful() const;
void set_request_id(int32_t request_id) { request_id_ = request_id; }
int32_t request_id() const { return request_id_; }
DECLARE_TRACE(); DECLARE_TRACE();
private: private:
...@@ -69,10 +66,6 @@ class WorkletScriptLoader final ...@@ -69,10 +66,6 @@ class WorkletScriptLoader final
Member<ResourceFetcher> fetcher_; Member<ResourceFetcher> fetcher_;
Member<Client> client_; Member<Client> client_;
// The client of this loader can freely use this field to identify a fetch
// request.
int32_t request_id_ = -1;
bool was_script_load_successful_ = false; bool was_script_load_successful_ = false;
bool was_script_load_complete_ = false; bool was_script_load_complete_ = false;
}; };
......
...@@ -84,7 +84,8 @@ blink_core_sources("workers") { ...@@ -84,7 +84,8 @@ blink_core_sources("workers") {
"WorkletGlobalScope.cpp", "WorkletGlobalScope.cpp",
"WorkletGlobalScope.h", "WorkletGlobalScope.h",
"WorkletGlobalScopeProxy.h", "WorkletGlobalScopeProxy.h",
"WorkletObjectProxy.h", "WorkletPendingTasks.cpp",
"WorkletPendingTasks.h",
"WorkletThreadHolder.h", "WorkletThreadHolder.h",
] ]
......
...@@ -11,27 +11,17 @@ ...@@ -11,27 +11,17 @@
#include "core/dom/ExceptionCode.h" #include "core/dom/ExceptionCode.h"
#include "core/frame/LocalFrame.h" #include "core/frame/LocalFrame.h"
#include "core/workers/WorkletGlobalScopeProxy.h" #include "core/workers/WorkletGlobalScopeProxy.h"
#include "core/workers/WorkletPendingTasks.h"
#include "platform/wtf/WTF.h" #include "platform/wtf/WTF.h"
namespace blink { namespace blink {
namespace { MainThreadWorklet::MainThreadWorklet(LocalFrame* frame) : Worklet(frame) {}
int32_t GetNextRequestId() {
DCHECK(IsMainThread());
static int32_t next_request_id = 1;
CHECK_LT(next_request_id, std::numeric_limits<int32_t>::max());
return next_request_id++;
}
} // namespace
MainThreadWorklet::MainThreadWorklet(LocalFrame* frame) : Worklet(frame) {
DCHECK(resolver_map_.IsEmpty());
}
// Implementation of the "addModule(moduleURL, options)" algorithm:
// https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule
ScriptPromise MainThreadWorklet::addModule(ScriptState* script_state, ScriptPromise MainThreadWorklet::addModule(ScriptState* script_state,
const String& url) { const String& module_url) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (!GetExecutionContext()) { if (!GetExecutionContext()) {
return ScriptPromise::RejectWithDOMException( return ScriptPromise::RejectWithDOMException(
...@@ -39,44 +29,44 @@ ScriptPromise MainThreadWorklet::addModule(ScriptState* script_state, ...@@ -39,44 +29,44 @@ ScriptPromise MainThreadWorklet::addModule(ScriptState* script_state,
"This frame is already detached")); "This frame is already detached"));
} }
KURL script_url = GetExecutionContext()->CompleteURL(url); KURL module_url_record = GetExecutionContext()->CompleteURL(module_url);
if (!script_url.IsValid()) { if (!module_url_record.IsValid()) {
return ScriptPromise::RejectWithDOMException( return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create( script_state,
kSyntaxError, "'" + url + "' is not a valid URL.")); DOMException::Create(kSyntaxError,
"'" + module_url + "' is not a valid URL."));
} }
int32_t request_id = GetNextRequestId();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise(); ScriptPromise promise = resolver->Promise();
resolver_map_.Set(request_id, resolver);
GetWorkletGlobalScopeProxy()->FetchAndInvokeScript(request_id, script_url);
return promise;
}
void MainThreadWorklet::DidFetchAndInvokeScript(int32_t request_id, // Step 11: "Let pendingTaskStruct be a new pending tasks struct with counter
bool success) { // initialized to the length of worklet's WorkletGlobalScopes."
DCHECK(IsMainThread()); // TODO(nhiroki): Introduce the concept of "worklet's WorkletGlobalScopes" and
ScriptPromiseResolver* resolver = resolver_map_.at(request_id); // use the length of it here.
if (!resolver) constexpr int number_of_global_scopes = 1;
return; WorkletPendingTasks* pending_tasks =
resolver_map_.erase(request_id); new WorkletPendingTasks(number_of_global_scopes, resolver);
if (!success) {
resolver->Reject(DOMException::Create(kNetworkError)); // Step 12: "For each workletGlobalScope in the worklet's
return; // WorkletGlobalScopes, queue a task on the workletGlobalScope to fetch and
} // invoke a worklet script given workletGlobalScope, moduleURLRecord,
resolver->Resolve(); // moduleResponsesMap, credentialOptions, outsideSettings, pendingTaskStruct,
// and promise."
// TODO(nhiroki): Pass the remaining parameters (e.g., credentialOptions).
// TODO(nhiroki): Queue a task instead of executing this here.
GetWorkletGlobalScopeProxy()->FetchAndInvokeScript(module_url_record,
pending_tasks);
return promise;
} }
void MainThreadWorklet::ContextDestroyed(ExecutionContext* execution_context) { void MainThreadWorklet::ContextDestroyed(ExecutionContext* execution_context) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
resolver_map_.clear();
GetWorkletGlobalScopeProxy()->TerminateWorkletGlobalScope(); GetWorkletGlobalScopeProxy()->TerminateWorkletGlobalScope();
Worklet::ContextDestroyed(execution_context); Worklet::ContextDestroyed(execution_context);
} }
DEFINE_TRACE(MainThreadWorklet) { DEFINE_TRACE(MainThreadWorklet) {
visitor->Trace(resolver_map_);
Worklet::Trace(visitor); Worklet::Trace(visitor);
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "bindings/core/v8/ScriptPromiseResolver.h" #include "bindings/core/v8/ScriptPromiseResolver.h"
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "core/workers/WorkletObjectProxy.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
namespace blink { namespace blink {
...@@ -20,8 +19,7 @@ class LocalFrame; ...@@ -20,8 +19,7 @@ class LocalFrame;
// TODO(nhiroki): This is a temporary class to support module loading for main // TODO(nhiroki): This is a temporary class to support module loading for main
// thread worklets. This and ThreadedWorklet will be merged into the base // thread worklets. This and ThreadedWorklet will be merged into the base
// Worklet class once threaded worklets are ready to use module loading. // Worklet class once threaded worklets are ready to use module loading.
class CORE_EXPORT MainThreadWorklet : public Worklet, class CORE_EXPORT MainThreadWorklet : public Worklet {
public WorkletObjectProxy {
USING_GARBAGE_COLLECTED_MIXIN(MainThreadWorklet); USING_GARBAGE_COLLECTED_MIXIN(MainThreadWorklet);
WTF_MAKE_NONCOPYABLE(MainThreadWorklet); WTF_MAKE_NONCOPYABLE(MainThreadWorklet);
...@@ -29,22 +27,15 @@ class CORE_EXPORT MainThreadWorklet : public Worklet, ...@@ -29,22 +27,15 @@ class CORE_EXPORT MainThreadWorklet : public Worklet,
virtual ~MainThreadWorklet() = default; virtual ~MainThreadWorklet() = default;
// Worklet // Worklet
ScriptPromise addModule(ScriptState*, const String& url) final; ScriptPromise addModule(ScriptState*, const String& module_url) final;
// ContextLifecycleObserver // ContextLifecycleObserver
void ContextDestroyed(ExecutionContext*) final; void ContextDestroyed(ExecutionContext*) final;
// WorkletObjectProxy
void DidFetchAndInvokeScript(int32_t request_id, bool success) final;
DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE();
protected: protected:
explicit MainThreadWorklet(LocalFrame*); explicit MainThreadWorklet(LocalFrame*);
private:
HeapHashMap<int32_t /* request_id */, Member<ScriptPromiseResolver>>
resolver_map_;
}; };
} // namespace blink } // namespace blink
......
...@@ -19,11 +19,9 @@ MainThreadWorkletGlobalScope::MainThreadWorkletGlobalScope( ...@@ -19,11 +19,9 @@ MainThreadWorkletGlobalScope::MainThreadWorkletGlobalScope(
const KURL& url, const KURL& url,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin> security_origin, PassRefPtr<SecurityOrigin> security_origin,
v8::Isolate* isolate, v8::Isolate* isolate)
WorkletObjectProxy* object_proxy)
: WorkletGlobalScope(url, user_agent, std::move(security_origin), isolate), : WorkletGlobalScope(url, user_agent, std::move(security_origin), isolate),
ContextClient(frame), ContextClient(frame) {}
object_proxy_(object_proxy) {}
MainThreadWorkletGlobalScope::~MainThreadWorkletGlobalScope() {} MainThreadWorkletGlobalScope::~MainThreadWorkletGlobalScope() {}
...@@ -48,16 +46,23 @@ WorkerThread* MainThreadWorkletGlobalScope::GetThread() const { ...@@ -48,16 +46,23 @@ WorkerThread* MainThreadWorkletGlobalScope::GetThread() const {
return nullptr; return nullptr;
} }
// Implementation of the first half of the "fetch and invoke a worklet script"
// algorithm:
// https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
void MainThreadWorkletGlobalScope::FetchAndInvokeScript( void MainThreadWorkletGlobalScope::FetchAndInvokeScript(
int32_t request_id, const KURL& module_url_record,
const KURL& script_url) { WorkletPendingTasks* pending_tasks) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
// Step 1: "Let insideSettings be the workletGlobalScope's associated
// environment settings object."
// Step 2: "Let script by the result of fetch a worklet script given
// moduleURLRecord, moduleResponsesMap, credentialOptions, outsideSettings,
// and insideSettings when it asynchronously completes."
// TODO(nhiroki): Replace this with module script loading. // TODO(nhiroki): Replace this with module script loading.
WorkletScriptLoader* script_loader = WorkletScriptLoader* script_loader =
WorkletScriptLoader::Create(GetFrame()->GetDocument()->Fetcher(), this); WorkletScriptLoader::Create(GetFrame()->GetDocument()->Fetcher(), this);
script_loader->set_request_id(request_id); loader_map_.Set(script_loader, pending_tasks);
loader_set_.insert(script_loader); script_loader->FetchScript(module_url_record);
script_loader->FetchScript(script_url);
} }
void MainThreadWorkletGlobalScope::EvaluateScript( void MainThreadWorkletGlobalScope::EvaluateScript(
...@@ -67,22 +72,47 @@ void MainThreadWorkletGlobalScope::EvaluateScript( ...@@ -67,22 +72,47 @@ void MainThreadWorkletGlobalScope::EvaluateScript(
NOTREACHED(); NOTREACHED();
} }
// TODO(nhiroki): Add tests for termination.
void MainThreadWorkletGlobalScope::TerminateWorkletGlobalScope() { void MainThreadWorkletGlobalScope::TerminateWorkletGlobalScope() {
for (const auto& script_loader : loader_set_) for (auto it = loader_map_.begin(); it != loader_map_.end();) {
WorkletScriptLoader* script_loader = it->key;
// Cancel() eventually calls NotifyWorkletScriptLoadingFinished() and
// removes |it| from |loader_map_|, so increment it in advance.
++it;
script_loader->Cancel(); script_loader->Cancel();
}
Dispose(); Dispose();
} }
// Implementation of the second half of the "fetch and invoke a worklet script"
// algorithm:
// https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
void MainThreadWorkletGlobalScope::NotifyWorkletScriptLoadingFinished( void MainThreadWorkletGlobalScope::NotifyWorkletScriptLoadingFinished(
WorkletScriptLoader* script_loader, WorkletScriptLoader* script_loader,
const ScriptSourceCode& source_code) { const ScriptSourceCode& source_code) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
int32_t request_id = script_loader->request_id(); auto it = loader_map_.find(script_loader);
loader_set_.erase(script_loader); DCHECK(it != loader_map_.end());
bool success = script_loader->WasScriptLoadSuccessful(); WorkletPendingTasks* pending_tasks = it->value;
if (success) loader_map_.erase(it);
if (!script_loader->WasScriptLoadSuccessful()) {
// Step 3: "If script is null, then queue a task on outsideSettings's
// responsible event loop to run these steps:"
// The steps are implemented in WorkletPendingTasks::Abort().
// TODO(nhiroki): Queue a task instead of executing this here.
pending_tasks->Abort();
return;
}
// Step 4: "Run a module script given script."
ScriptController()->Evaluate(source_code); ScriptController()->Evaluate(source_code);
object_proxy_->DidFetchAndInvokeScript(request_id, success);
// Step 5: "Queue a task on outsideSettings's responsible event loop to run
// these steps:"
// The steps are implemented in WorkletPendingTasks::DecrementCounter().
// TODO(nhiroki): Queue a task instead of executing this here.
pending_tasks->DecrementCounter();
} }
void MainThreadWorkletGlobalScope::AddConsoleMessage( void MainThreadWorkletGlobalScope::AddConsoleMessage(
...@@ -95,8 +125,7 @@ void MainThreadWorkletGlobalScope::ExceptionThrown(ErrorEvent* event) { ...@@ -95,8 +125,7 @@ void MainThreadWorkletGlobalScope::ExceptionThrown(ErrorEvent* event) {
} }
DEFINE_TRACE(MainThreadWorkletGlobalScope) { DEFINE_TRACE(MainThreadWorkletGlobalScope) {
visitor->Trace(loader_set_); visitor->Trace(loader_map_);
visitor->Trace(object_proxy_);
WorkletGlobalScope::Trace(visitor); WorkletGlobalScope::Trace(visitor);
ContextClient::Trace(visitor); ContextClient::Trace(visitor);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "core/loader/WorkletScriptLoader.h" #include "core/loader/WorkletScriptLoader.h"
#include "core/workers/WorkletGlobalScope.h" #include "core/workers/WorkletGlobalScope.h"
#include "core/workers/WorkletGlobalScopeProxy.h" #include "core/workers/WorkletGlobalScopeProxy.h"
#include "core/workers/WorkletObjectProxy.h" #include "core/workers/WorkletPendingTasks.h"
namespace blink { namespace blink {
...@@ -31,8 +31,7 @@ class CORE_EXPORT MainThreadWorkletGlobalScope ...@@ -31,8 +31,7 @@ class CORE_EXPORT MainThreadWorkletGlobalScope
const KURL&, const KURL&,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin>, PassRefPtr<SecurityOrigin>,
v8::Isolate*, v8::Isolate*);
WorkletObjectProxy*);
~MainThreadWorkletGlobalScope() override; ~MainThreadWorkletGlobalScope() override;
bool IsMainThreadWorkletGlobalScope() const final { return true; } bool IsMainThreadWorkletGlobalScope() const final { return true; }
...@@ -42,7 +41,8 @@ class CORE_EXPORT MainThreadWorkletGlobalScope ...@@ -42,7 +41,8 @@ class CORE_EXPORT MainThreadWorkletGlobalScope
WorkerThread* GetThread() const final; WorkerThread* GetThread() const final;
// WorkletGlobalScopeProxy // WorkletGlobalScopeProxy
void FetchAndInvokeScript(int32_t request_id, const KURL& script_url) final; void FetchAndInvokeScript(const KURL& module_url_record,
WorkletPendingTasks*) final;
void EvaluateScript(const ScriptSourceCode&) final; void EvaluateScript(const ScriptSourceCode&) final;
void TerminateWorkletGlobalScope() final; void TerminateWorkletGlobalScope() final;
...@@ -57,9 +57,8 @@ class CORE_EXPORT MainThreadWorkletGlobalScope ...@@ -57,9 +57,8 @@ class CORE_EXPORT MainThreadWorkletGlobalScope
DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE();
private: private:
HeapHashSet<Member<WorkletScriptLoader>> loader_set_; HeapHashMap<Member<WorkletScriptLoader>, Member<WorkletPendingTasks>>
loader_map_;
Member<WorkletObjectProxy> object_proxy_;
}; };
DEFINE_TYPE_CASTS(MainThreadWorkletGlobalScope, DEFINE_TYPE_CASTS(MainThreadWorkletGlobalScope,
......
...@@ -11,19 +11,6 @@ ...@@ -11,19 +11,6 @@
namespace blink { namespace blink {
namespace {
class WorkletObjectProxyForTest final
: public GarbageCollectedFinalized<WorkletObjectProxyForTest>,
public WorkletObjectProxy {
USING_GARBAGE_COLLECTED_MIXIN(WorkletObjectProxyForTest);
public:
void DidFetchAndInvokeScript(int32_t request_id, bool success) {}
};
} // namespace
class MainThreadWorkletTest : public ::testing::Test { class MainThreadWorkletTest : public ::testing::Test {
public: public:
void SetUp() override { void SetUp() override {
...@@ -32,8 +19,7 @@ class MainThreadWorkletTest : public ::testing::Test { ...@@ -32,8 +19,7 @@ class MainThreadWorkletTest : public ::testing::Test {
security_origin_ = SecurityOrigin::Create(url); security_origin_ = SecurityOrigin::Create(url);
global_scope_ = new MainThreadWorkletGlobalScope( global_scope_ = new MainThreadWorkletGlobalScope(
&page_->GetFrame(), url, "fake user agent", security_origin_.Get(), &page_->GetFrame(), url, "fake user agent", security_origin_.Get(),
ToIsolate(page_->GetFrame().GetDocument()), ToIsolate(page_->GetFrame().GetDocument()));
new WorkletObjectProxyForTest);
} }
void TearDown() override { global_scope_->TerminateWorkletGlobalScope(); } void TearDown() override { global_scope_->TerminateWorkletGlobalScope(); }
......
...@@ -34,7 +34,7 @@ class CORE_EXPORT ThreadedWorklet : public Worklet, ...@@ -34,7 +34,7 @@ class CORE_EXPORT ThreadedWorklet : public Worklet,
virtual bool IsInitialized() const = 0; virtual bool IsInitialized() const = 0;
// Worklet // Worklet
ScriptPromise addModule(ScriptState*, const String& url) final; ScriptPromise addModule(ScriptState*, const String& module_url) final;
// WorkletScriptLoader::Client // WorkletScriptLoader::Client
void NotifyWorkletScriptLoadingFinished(WorkletScriptLoader*, void NotifyWorkletScriptLoadingFinished(WorkletScriptLoader*,
......
...@@ -32,7 +32,7 @@ class CORE_EXPORT Worklet : public GarbageCollectedFinalized<Worklet>, ...@@ -32,7 +32,7 @@ class CORE_EXPORT Worklet : public GarbageCollectedFinalized<Worklet>,
// Worklet.idl // Worklet.idl
// addModule() imports ES6 module scripts. // addModule() imports ES6 module scripts.
virtual ScriptPromise addModule(ScriptState*, const String& url) = 0; virtual ScriptPromise addModule(ScriptState*, const String& module_url) = 0;
// Returns a proxy to WorkletGlobalScope on the context thread. // Returns a proxy to WorkletGlobalScope on the context thread.
virtual WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const = 0; virtual WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const = 0;
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "platform/weborigin/KURL.h" #include "platform/weborigin/KURL.h"
#include "platform/wtf/text/WTFString.h"
namespace blink { namespace blink {
class ScriptSourceCode; class ScriptSourceCode;
class WorkletPendingTasks;
// A proxy to talk to the worklet global scope. The global scope may exist in // A proxy to talk to the worklet global scope. The global scope may exist in
// the main thread or on a different thread. // the main thread or on a different thread.
...@@ -21,8 +21,8 @@ class CORE_EXPORT WorkletGlobalScopeProxy { ...@@ -21,8 +21,8 @@ class CORE_EXPORT WorkletGlobalScopeProxy {
// Runs the "fetch and invoke a worklet script" algorithm: // Runs the "fetch and invoke a worklet script" algorithm:
// https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
virtual void FetchAndInvokeScript(int32_t request_id, virtual void FetchAndInvokeScript(const KURL& module_url_record,
const KURL& script_url) {} WorkletPendingTasks*) {}
// Evaluates the given script source code. This should be called only for // Evaluates the given script source code. This should be called only for
// threaded worklets that still use classic script loading. // threaded worklets that still use classic script loading.
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WorkletObjectProxy_h
#define WorkletObjectProxy_h
#include "core/CoreExport.h"
#include "platform/heap/GarbageCollected.h"
#include "platform/weborigin/KURL.h"
#include "platform/wtf/text/WTFString.h"
namespace blink {
// A proxy to talk to the Worklet object on the main thread from the worklet
// global scope that may exist in the main thread or on a different thread.
class CORE_EXPORT WorkletObjectProxy : public GarbageCollectedMixin {
public:
// Called when the worklet module script is fetched and evaluated. |success|
// is true if the sequence is completed without an error.
virtual void DidFetchAndInvokeScript(int32_t request_id, bool success) = 0;
};
} // namespace blink
#endif // WorkletObjectProxy_h
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/workers/WorkletPendingTasks.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
#include "platform/wtf/WTF.h"
namespace blink {
WorkletPendingTasks::WorkletPendingTasks(int counter,
ScriptPromiseResolver* resolver)
: counter_(counter), resolver_(resolver) {
DCHECK(IsMainThread());
}
void WorkletPendingTasks::Abort() {
DCHECK(IsMainThread());
// Step 3: "If script is null, then queue a task on outsideSettings's
// responsible event loop to run these steps:"
// 1: "If pendingTaskStruct's counter is not -1, then run these steps:"
// 1: "Set pendingTaskStruct's counter to -1."
// 2: "Reject promise with an "AbortError" DOMException."
if (counter_ != -1) {
counter_ = -1;
// TODO(nhiroki): This should be kAbortError.
resolver_->Reject(DOMException::Create(kNetworkError));
}
}
void WorkletPendingTasks::DecrementCounter() {
DCHECK(IsMainThread());
// Step 5: "Queue a task on outsideSettings's responsible event loop to run
// these steps:"
// 1: "If pendingTaskStruct's counter is not -1, then run these steps:"
// 1: "Decrement pendingTaskStruct's counter by 1."
// 2: "If pendingTaskStruct's counter is 0, then resolve promise."
if (counter_ != -1) {
--counter_;
if (counter_ == 0)
resolver_->Resolve();
}
}
} // namespace blink
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WorkletPendingTasks_h
#define WorkletPendingTasks_h
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "platform/heap/Heap.h"
namespace blink {
// Implementation of the "pending tasks struct":
// https://drafts.css-houdini.org/worklets/#pending-tasks-struct
//
// This also implements a part of the "fetch and invoke a worklet script"
// algorithm:
// https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
//
// All functions must be accessed on the main thread.
class WorkletPendingTasks final : public GarbageCollected<WorkletPendingTasks> {
public:
WorkletPendingTasks(int counter, ScriptPromiseResolver*);
// Sets |counter_| to -1 and rejects the promise.
void Abort();
// Decrements |counter_| and resolves the promise if the counter becomes 0.
void DecrementCounter();
DEFINE_INLINE_VIRTUAL_TRACE() { visitor->Trace(resolver_); }
private:
// The number of pending tasks. -1 indicates these tasks are aborted and
// |resolver_| already rejected the promise.
int counter_;
Member<ScriptPromiseResolver> resolver_;
};
} // namespace blink
#endif // WorkletPendingTasks_h
...@@ -23,8 +23,7 @@ PaintWorklet::PaintWorklet(LocalFrame* frame) ...@@ -23,8 +23,7 @@ PaintWorklet::PaintWorklet(LocalFrame* frame)
frame->GetDocument()->Url(), frame->GetDocument()->Url(),
frame->GetDocument()->UserAgent(), frame->GetDocument()->UserAgent(),
frame->GetDocument()->GetSecurityOrigin(), frame->GetDocument()->GetSecurityOrigin(),
ToIsolate(frame->GetDocument()), ToIsolate(frame->GetDocument()))) {}
this)) {}
PaintWorklet::~PaintWorklet() {} PaintWorklet::~PaintWorklet() {}
......
...@@ -23,12 +23,10 @@ PaintWorkletGlobalScope* PaintWorkletGlobalScope::Create( ...@@ -23,12 +23,10 @@ PaintWorkletGlobalScope* PaintWorkletGlobalScope::Create(
const KURL& url, const KURL& url,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin> security_origin, PassRefPtr<SecurityOrigin> security_origin,
v8::Isolate* isolate, v8::Isolate* isolate) {
WorkletObjectProxy* object_proxy) {
PaintWorkletGlobalScope* paint_worklet_global_scope = PaintWorkletGlobalScope* paint_worklet_global_scope =
new PaintWorkletGlobalScope(frame, url, user_agent, new PaintWorkletGlobalScope(frame, url, user_agent,
std::move(security_origin), isolate, std::move(security_origin), isolate);
object_proxy);
paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded(); paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded();
MainThreadDebugger::Instance()->ContextCreated( MainThreadDebugger::Instance()->ContextCreated(
paint_worklet_global_scope->ScriptController()->GetScriptState(), paint_worklet_global_scope->ScriptController()->GetScriptState(),
...@@ -42,14 +40,12 @@ PaintWorkletGlobalScope::PaintWorkletGlobalScope( ...@@ -42,14 +40,12 @@ PaintWorkletGlobalScope::PaintWorkletGlobalScope(
const KURL& url, const KURL& url,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin> security_origin, PassRefPtr<SecurityOrigin> security_origin,
v8::Isolate* isolate, v8::Isolate* isolate)
WorkletObjectProxy* object_proxy)
: MainThreadWorkletGlobalScope(frame, : MainThreadWorkletGlobalScope(frame,
url, url,
user_agent, user_agent,
std::move(security_origin), std::move(security_origin),
isolate, isolate) {}
object_proxy) {}
PaintWorkletGlobalScope::~PaintWorkletGlobalScope() {} PaintWorkletGlobalScope::~PaintWorkletGlobalScope() {}
......
...@@ -27,8 +27,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final ...@@ -27,8 +27,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final
const KURL&, const KURL&,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin>, PassRefPtr<SecurityOrigin>,
v8::Isolate*, v8::Isolate*);
WorkletObjectProxy*);
~PaintWorkletGlobalScope() override; ~PaintWorkletGlobalScope() override;
void Dispose() final; void Dispose() final;
...@@ -47,8 +46,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final ...@@ -47,8 +46,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final
const KURL&, const KURL&,
const String& user_agent, const String& user_agent,
PassRefPtr<SecurityOrigin>, PassRefPtr<SecurityOrigin>,
v8::Isolate*, v8::Isolate*);
WorkletObjectProxy*);
typedef HeapHashMap<String, Member<CSSPaintDefinition>> DefinitionMap; typedef HeapHashMap<String, Member<CSSPaintDefinition>> DefinitionMap;
DefinitionMap paint_definitions_; DefinitionMap paint_definitions_;
......
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