Commit 6d12f07b authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Make ThreadPoolTask oilpan-friendly and merge it in to Task

Change-Id: I94ade605404051bf0d735b936923c2084bb805bc
Reviewed-on: https://chromium-review.googlesource.com/c/1316436
Commit-Queue: Nate Chapin <japhet@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605457}
parent 2a90bffa
...@@ -17,10 +17,11 @@ ...@@ -17,10 +17,11 @@
namespace blink { namespace blink {
class ThreadPoolTask::AsyncFunctionCompleted : public ScriptFunction { // worker_thread_ only.
class Task::AsyncFunctionCompleted : public ScriptFunction {
public: public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
ThreadPoolTask* task, Task* task,
State state) { State state) {
return (new AsyncFunctionCompleted(script_state, task, state)) return (new AsyncFunctionCompleted(script_state, task, state))
->BindToV8Function(); ->BindToV8Function();
...@@ -32,50 +33,47 @@ class ThreadPoolTask::AsyncFunctionCompleted : public ScriptFunction { ...@@ -32,50 +33,47 @@ class ThreadPoolTask::AsyncFunctionCompleted : public ScriptFunction {
} }
private: private:
AsyncFunctionCompleted(ScriptState* script_state, AsyncFunctionCompleted(ScriptState* script_state, Task* task, State state)
ThreadPoolTask* task,
State state)
: ScriptFunction(script_state), task_(task), state_(state) {} : ScriptFunction(script_state), task_(task), state_(state) {}
ThreadPoolTask* task_; CrossThreadPersistent<Task> task_;
const State state_; const State state_;
}; };
ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, Task::Task(ThreadPoolThreadProvider* thread_provider,
ScriptState* script_state, ScriptState* script_state,
const ScriptValue& function, const ScriptValue& function,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType task_type) TaskType task_type)
: ThreadPoolTask(thread_provider, : Task(thread_provider,
script_state, script_state,
function, function,
String(), String(),
arguments, arguments,
task_type) {} task_type) {}
ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, Task::Task(ThreadPoolThreadProvider* thread_provider,
ScriptState* script_state, ScriptState* script_state,
const String& function_name, const String& function_name,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType task_type) TaskType task_type)
: ThreadPoolTask(thread_provider, : Task(thread_provider,
script_state, script_state,
ScriptValue(), ScriptValue(),
function_name, function_name,
arguments, arguments,
task_type) {} task_type) {}
ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, Task::Task(ThreadPoolThreadProvider* thread_provider,
ScriptState* script_state, ScriptState* script_state,
const ScriptValue& function, const ScriptValue& function,
const String& function_name, const String& function_name,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType task_type) TaskType task_type)
: task_type_(task_type), : task_type_(task_type),
self_keep_alive_(base::AdoptRef(this)), self_keep_alive_(this),
resolver_(ScriptPromiseResolver::Create(script_state)), resolver_(ScriptPromiseResolver::Create(script_state)),
function_name_(function_name.IsolatedCopy()), function_name_(function_name.IsolatedCopy()),
arguments_(arguments.size()), arguments_(arguments.size()) {
weak_factory_(this) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
DCHECK_EQ(!function.IsEmpty(), function_name.IsNull()); DCHECK_EQ(!function.IsEmpty(), function_name.IsNull());
DCHECK(task_type_ == TaskType::kUserInteraction || DCHECK(task_type_ == TaskType::kUserInteraction ||
...@@ -88,7 +86,7 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, ...@@ -88,7 +86,7 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider,
isolate, function.V8Value()->ToString(isolate)); isolate, function.V8Value()->ToString(isolate));
} }
Vector<ThreadPoolTask*> prerequisites; HeapVector<Member<Task>> prerequisites;
Vector<size_t> prerequisites_indices; Vector<size_t> prerequisites_indices;
for (size_t i = 0; i < arguments_.size(); i++) { for (size_t i = 0; i < arguments_.size(); i++) {
// Normal case: if the argument isn't a Task, just serialize it. // Normal case: if the argument isn't a Task, just serialize it.
...@@ -98,10 +96,9 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, ...@@ -98,10 +96,9 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider,
isolate, arguments[i].V8Value()); isolate, arguments[i].V8Value());
continue; continue;
} }
ThreadPoolTask* prerequisite = Task* prerequisite =
ToScriptWrappable(arguments[i].V8Value().As<v8::Object>()) ToScriptWrappable(arguments[i].V8Value().As<v8::Object>())
->ToImpl<Task>() ->ToImpl<Task>();
->GetThreadPoolTask();
prerequisites.push_back(prerequisite); prerequisites.push_back(prerequisite);
prerequisites_indices.push_back(i); prerequisites_indices.push_back(i);
} }
...@@ -114,7 +111,7 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, ...@@ -114,7 +111,7 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider,
return; return;
} }
// Prior to this point, other ThreadPoolTask instances don't have a reference // Prior to this point, other Task instances don't have a reference
// to |this| yet, so no need to lock mutex_. RegisterDependencies() populates // to |this| yet, so no need to lock mutex_. RegisterDependencies() populates
// those references, so RegisterDependencies() and any logic thereafter must // those references, so RegisterDependencies() and any logic thereafter must
// consider the potential for data races. // consider the potential for data races.
...@@ -122,14 +119,14 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider, ...@@ -122,14 +119,14 @@ ThreadPoolTask::ThreadPoolTask(ThreadPoolThreadProvider* thread_provider,
} }
// static // static
ThreadPoolThread* ThreadPoolTask::SelectThread( ThreadPoolThread* Task::SelectThread(
const Vector<ThreadPoolTask*>& prerequisites, const HeapVector<Member<Task>>& prerequisites,
ThreadPoolThreadProvider* thread_provider) { ThreadPoolThreadProvider* thread_provider) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
HashCountedSet<ThreadPoolThread*> prerequisite_location_counts; HashCountedSet<ThreadPoolThread*> prerequisite_location_counts;
size_t max_prerequisite_location_count = 0; size_t max_prerequisite_location_count = 0;
ThreadPoolThread* max_prerequisite_thread = nullptr; ThreadPoolThread* max_prerequisite_thread = nullptr;
for (ThreadPoolTask* prerequisite : prerequisites) { for (Task* prerequisite : prerequisites) {
// For prerequisites that are not yet complete, track which thread the task // For prerequisites that are not yet complete, track which thread the task
// will run on. Put this task on the thread where the most prerequisites // will run on. Put this task on the thread where the most prerequisites
// reside. This is slightly imprecise, because a task may complete before // reside. This is slightly imprecise, because a task may complete before
...@@ -147,7 +144,7 @@ ThreadPoolThread* ThreadPoolTask::SelectThread( ...@@ -147,7 +144,7 @@ ThreadPoolThread* ThreadPoolTask::SelectThread(
: thread_provider->GetLeastBusyThread(); : thread_provider->GetLeastBusyThread();
} }
ThreadPoolThread* ThreadPoolTask::GetScheduledThread() { ThreadPoolThread* Task::GetScheduledThread() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
MutexLocker lock(mutex_); MutexLocker lock(mutex_);
return HasFinished() ? nullptr : worker_thread_; return HasFinished() ? nullptr : worker_thread_;
...@@ -155,9 +152,8 @@ ThreadPoolThread* ThreadPoolTask::GetScheduledThread() { ...@@ -155,9 +152,8 @@ ThreadPoolThread* ThreadPoolTask::GetScheduledThread() {
// Should only be called from constructor. Split out in to a helper because // Should only be called from constructor. Split out in to a helper because
// clang appears to exempt constructors from thread safety analysis. // clang appears to exempt constructors from thread safety analysis.
void ThreadPoolTask::RegisterDependencies( void Task::RegisterDependencies(const HeapVector<Member<Task>>& prerequisites,
const Vector<ThreadPoolTask*>& prerequisites, const Vector<size_t>& prerequisites_indices) {
const Vector<size_t>& prerequisites_indices) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
{ {
MutexLocker lock(mutex_); MutexLocker lock(mutex_);
...@@ -165,7 +161,7 @@ void ThreadPoolTask::RegisterDependencies( ...@@ -165,7 +161,7 @@ void ThreadPoolTask::RegisterDependencies(
} }
for (size_t i = 0; i < prerequisites.size(); i++) { for (size_t i = 0; i < prerequisites.size(); i++) {
ThreadPoolTask* prerequisite = prerequisites[i]; Task* prerequisite = prerequisites[i];
size_t prerequisite_index = prerequisites_indices[i]; size_t prerequisite_index = prerequisites_indices[i];
scoped_refptr<SerializedScriptValue> result; scoped_refptr<SerializedScriptValue> result;
State prerequisite_state = State::kPending; State prerequisite_state = State::kPending;
...@@ -176,8 +172,8 @@ void ThreadPoolTask::RegisterDependencies( ...@@ -176,8 +172,8 @@ void ThreadPoolTask::RegisterDependencies(
if (prerequisite->HasFinished()) { if (prerequisite->HasFinished()) {
result = prerequisite->serialized_result_; result = prerequisite->serialized_result_;
} else { } else {
prerequisite->dependents_.insert( prerequisite->dependents_.emplace_back(
std::make_unique<Dependent>(this, prerequisite_index)); new Dependent(this, prerequisite_index));
} }
} }
...@@ -191,7 +187,7 @@ void ThreadPoolTask::RegisterDependencies( ...@@ -191,7 +187,7 @@ void ThreadPoolTask::RegisterDependencies(
} }
} }
ThreadPoolTask::~ThreadPoolTask() { Task::~Task() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
DCHECK(HasFinished()); DCHECK(HasFinished());
DCHECK(!function_); DCHECK(!function_);
...@@ -200,11 +196,10 @@ ThreadPoolTask::~ThreadPoolTask() { ...@@ -200,11 +196,10 @@ ThreadPoolTask::~ThreadPoolTask() {
DCHECK(dependents_.IsEmpty()); DCHECK(dependents_.IsEmpty());
} }
void ThreadPoolTask::PrerequisiteFinished( void Task::PrerequisiteFinished(size_t prerequisite_index,
size_t prerequisite_index, v8::Local<v8::Value> v8_result,
v8::Local<v8::Value> v8_result, scoped_refptr<SerializedScriptValue> result,
scoped_refptr<SerializedScriptValue> result, State prerequisite_state) {
State prerequisite_state) {
MutexLocker lock(mutex_); MutexLocker lock(mutex_);
DCHECK(state_ == State::kPending || state_ == State::kCancelPending); DCHECK(state_ == State::kPending || state_ == State::kCancelPending);
DCHECK(prerequisite_state == State::kCompleted || DCHECK(prerequisite_state == State::kCompleted ||
...@@ -225,16 +220,16 @@ void ThreadPoolTask::PrerequisiteFinished( ...@@ -225,16 +220,16 @@ void ThreadPoolTask::PrerequisiteFinished(
MaybeStartTask(); MaybeStartTask();
} }
void ThreadPoolTask::MaybeStartTask() { void Task::MaybeStartTask() {
if (prerequisites_remaining_) if (prerequisites_remaining_)
return; return;
DCHECK(state_ == State::kPending || state_ == State::kCancelPending); DCHECK(state_ == State::kPending || state_ == State::kCancelPending);
PostCrossThreadTask(*worker_thread_->GetTaskRunner(task_type_), FROM_HERE, PostCrossThreadTask(*worker_thread_->GetTaskRunner(task_type_), FROM_HERE,
CrossThreadBind(&ThreadPoolTask::StartTaskOnWorkerThread, CrossThreadBind(&Task::StartTaskOnWorkerThread,
CrossThreadUnretained(this))); WrapCrossThreadPersistent(this)));
} }
void ThreadPoolTask::StartTaskOnWorkerThread() { void Task::StartTaskOnWorkerThread() {
DCHECK(worker_thread_->IsCurrentThread()); DCHECK(worker_thread_->IsCurrentThread());
bool was_cancelled = false; bool was_cancelled = false;
...@@ -269,9 +264,8 @@ void ThreadPoolTask::StartTaskOnWorkerThread() { ...@@ -269,9 +264,8 @@ void ThreadPoolTask::StartTaskOnWorkerThread() {
RunTaskOnWorkerThread(); RunTaskOnWorkerThread();
} }
void ThreadPoolTask::TaskCompletedOnWorkerThread( void Task::TaskCompletedOnWorkerThread(v8::Local<v8::Value> return_value,
v8::Local<v8::Value> return_value, State state) {
State state) {
DCHECK(worker_thread_->IsCurrentThread()); DCHECK(worker_thread_->IsCurrentThread());
scoped_refptr<SerializedScriptValue> local_result = scoped_refptr<SerializedScriptValue> local_result =
...@@ -281,7 +275,7 @@ void ThreadPoolTask::TaskCompletedOnWorkerThread( ...@@ -281,7 +275,7 @@ void ThreadPoolTask::TaskCompletedOnWorkerThread(
function_ = nullptr; function_ = nullptr;
arguments_.clear(); arguments_.clear();
HashSet<std::unique_ptr<Dependent>> dependents_to_notify; Vector<CrossThreadPersistent<Dependent>> dependents_to_notify;
{ {
MutexLocker lock(mutex_); MutexLocker lock(mutex_);
serialized_result_ = local_result; serialized_result_ = local_result;
...@@ -298,12 +292,10 @@ void ThreadPoolTask::TaskCompletedOnWorkerThread( ...@@ -298,12 +292,10 @@ void ThreadPoolTask::TaskCompletedOnWorkerThread(
*worker_thread_->GetParentExecutionContextTaskRunners()->Get( *worker_thread_->GetParentExecutionContextTaskRunners()->Get(
TaskType::kInternalWorker), TaskType::kInternalWorker),
FROM_HERE, FROM_HERE,
CrossThreadBind(&ThreadPoolTask::TaskCompleted, CrossThreadBind(&Task::TaskCompleted, WrapCrossThreadPersistent(this)));
CrossThreadUnretained(this)));
// TaskCompleted may delete |this| at any time after this point.
} }
void ThreadPoolTask::RunTaskOnWorkerThread() { void Task::RunTaskOnWorkerThread() {
DCHECK(worker_thread_->IsCurrentThread()); DCHECK(worker_thread_->IsCurrentThread());
// No other thread should be touching function_ or arguments_ at this point, // No other thread should be touching function_ or arguments_ at this point,
// so no mutex needed while actually running the task. // so no mutex needed while actually running the task.
...@@ -378,7 +370,7 @@ void ThreadPoolTask::RunTaskOnWorkerThread() { ...@@ -378,7 +370,7 @@ void ThreadPoolTask::RunTaskOnWorkerThread() {
TaskCompletedOnWorkerThread(return_value, State::kCompleted); TaskCompletedOnWorkerThread(return_value, State::kCompleted);
} }
void ThreadPoolTask::TaskCompleted() { void Task::TaskCompleted() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
bool rejected = false; bool rejected = false;
{ {
...@@ -401,23 +393,22 @@ void ThreadPoolTask::TaskCompleted() { ...@@ -401,23 +393,22 @@ void ThreadPoolTask::TaskCompleted() {
resolver_->Resolve(value); resolver_->Resolve(value);
} }
worker_thread_->DecrementTasksInProgressCount(); worker_thread_->DecrementTasksInProgressCount();
self_keep_alive_.reset(); self_keep_alive_.Clear();
// |this| may be deleted here.
} }
ScriptPromise ThreadPoolTask::GetResult() { ScriptPromise Task::result() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
return resolver_->Promise(); return resolver_->Promise();
} }
void ThreadPoolTask::Cancel() { void Task::cancel() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
MutexLocker lock(mutex_); MutexLocker lock(mutex_);
if (state_ == State::kPending) if (state_ == State::kPending)
AdvanceState(State::kCancelPending); AdvanceState(State::kCancelPending);
} }
void ThreadPoolTask::AdvanceState(State new_state) { void Task::AdvanceState(State new_state) {
switch (new_state) { switch (new_state) {
case State::kPending: case State::kPending:
NOTREACHED() << "kPending should only be set via initialization"; NOTREACHED() << "kPending should only be set via initialization";
...@@ -438,4 +429,9 @@ void ThreadPoolTask::AdvanceState(State new_state) { ...@@ -438,4 +429,9 @@ void ThreadPoolTask::AdvanceState(State new_state) {
state_ = new_state; state_ = new_state;
} }
void Task::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
visitor->Trace(resolver_);
}
} // namespace blink } // namespace blink
...@@ -18,41 +18,40 @@ class SerializedScriptValue; ...@@ -18,41 +18,40 @@ class SerializedScriptValue;
// Scans |arguments| for Task objects, and registers those as dependencies, // Scans |arguments| for Task objects, and registers those as dependencies,
// passing the result of those tasks in place of the Task arguments. // passing the result of those tasks in place of the Task arguments.
// All public functions are main-thread-only. // All public functions are main-thread-only.
// ThreadPoolTask keeps itself alive via a self scoped_refptr until the // Task keeps itself alive via a SelfKeepAlive until the
// the task completes and reports itself done on the main thread via // the task completes and reports itself done on the main thread via
// TaskCompleted(). Other users (e.g. Task below) can keep the task // TaskCompleted().
// alive after completion. class Task final : public ScriptWrappable {
class ThreadPoolTask final : public RefCounted<ThreadPoolTask> { DEFINE_WRAPPERTYPEINFO();
public: public:
// Called on main thread // Called on main thread
ThreadPoolTask(ThreadPoolThreadProvider*, Task(ThreadPoolThreadProvider*,
ScriptState*, ScriptState*,
const ScriptValue& function, const ScriptValue& function,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType); TaskType);
ThreadPoolTask(ThreadPoolThreadProvider*, Task(ThreadPoolThreadProvider*,
ScriptState*, ScriptState*,
const String& function_name, const String& function_name,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType); TaskType);
~ThreadPoolTask(); ~Task() override;
// Returns a promise that will be resolved with the result when it completes. // Returns a promise that will be resolved with the result when it completes.
ScriptPromise GetResult(); ScriptPromise result();
void Cancel() LOCKS_EXCLUDED(mutex_); void cancel() LOCKS_EXCLUDED(mutex_);
base::WeakPtr<ThreadPoolTask> GetWeakPtr() { void Trace(Visitor*) override;
return weak_factory_.GetWeakPtr();
}
private: private:
enum class State { kPending, kStarted, kCancelPending, kCompleted, kFailed }; enum class State { kPending, kStarted, kCancelPending, kCompleted, kFailed };
ThreadPoolTask(ThreadPoolThreadProvider*, Task(ThreadPoolThreadProvider*,
ScriptState*, ScriptState*,
const ScriptValue& function, const ScriptValue& function,
const String& function_name, const String& function_name,
const Vector<ScriptValue>& arguments, const Vector<ScriptValue>& arguments,
TaskType); TaskType);
class AsyncFunctionCompleted; class AsyncFunctionCompleted;
...@@ -74,10 +73,10 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> { ...@@ -74,10 +73,10 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> {
// Called on main thread // Called on main thread
static ThreadPoolThread* SelectThread( static ThreadPoolThread* SelectThread(
const Vector<ThreadPoolTask*>& prerequisites, const HeapVector<Member<Task>>& prerequisites,
ThreadPoolThreadProvider*); ThreadPoolThreadProvider*);
ThreadPoolThread* GetScheduledThread() LOCKS_EXCLUDED(mutex_); ThreadPoolThread* GetScheduledThread() LOCKS_EXCLUDED(mutex_);
void RegisterDependencies(const Vector<ThreadPoolTask*>& prerequisites, void RegisterDependencies(const HeapVector<Member<Task>>& prerequisites,
const Vector<size_t>& prerequisite_indices) const Vector<size_t>& prerequisite_indices)
LOCKS_EXCLUDED(mutex_); LOCKS_EXCLUDED(mutex_);
void TaskCompleted(); void TaskCompleted();
...@@ -87,8 +86,8 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> { ...@@ -87,8 +86,8 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> {
const TaskType task_type_; const TaskType task_type_;
// Main thread only // Main thread only
scoped_refptr<ThreadPoolTask> self_keep_alive_; SelfKeepAlive<Task> self_keep_alive_;
Persistent<ScriptPromiseResolver> resolver_; Member<ScriptPromiseResolver> resolver_;
// Created in constructor on the main thread, consumed and cleared on // Created in constructor on the main thread, consumed and cleared on
// worker_thread_. Those steps can't overlap, so no mutex_ required. // worker_thread_. Those steps can't overlap, so no mutex_ required.
...@@ -120,38 +119,20 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> { ...@@ -120,38 +119,20 @@ class ThreadPoolTask final : public RefCounted<ThreadPoolTask> {
size_t prerequisites_remaining_ GUARDED_BY(mutex_) = 0u; size_t prerequisites_remaining_ GUARDED_BY(mutex_) = 0u;
// Elements added from main thread. Cleared on completion on worker_thread_. // Elements added from main thread. Cleared on completion on worker_thread_.
// Each element in dependents_ is not yet in the kCompleted state and // Each element in dependents_ is not yet in the kCompleted state.
// therefore is guaranteed to be alive. struct Dependent final : public GarbageCollected<Dependent> {
struct Dependent {
public: public:
Dependent(ThreadPoolTask* task, size_t index) : task(task), index(index) {} Dependent(Task* task, size_t index) : task(task), index(index) {
ThreadPoolTask* task; DCHECK(IsMainThread());
}
void Trace(Visitor* visitor) { visitor->Trace(task); }
Member<Task> task;
// The index in the dependent's argument array where this result should go.
size_t index; size_t index;
}; };
HashSet<std::unique_ptr<Dependent>> dependents_ GUARDED_BY(mutex_); Vector<CrossThreadPersistent<Dependent>> dependents_ GUARDED_BY(mutex_);
Mutex mutex_; Mutex mutex_;
base::WeakPtrFactory<ThreadPoolTask> weak_factory_;
};
// This is a thin, v8-exposed wrapper around ThreadPoolTask that allows
// ThreadPoolTask to avoid being GarbageCollected.
class Task : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit Task(ThreadPoolTask* thread_pool_task)
: thread_pool_task_(thread_pool_task) {}
~Task() override = default;
ScriptPromise result() { return thread_pool_task_->GetResult(); }
void cancel() { thread_pool_task_->Cancel(); }
ThreadPoolTask* GetThreadPoolTask() const { return thread_pool_task_.get(); }
private:
scoped_refptr<ThreadPoolTask> thread_pool_task_;
}; };
} // namespace blink } // namespace blink
......
...@@ -55,17 +55,14 @@ Task* TaskWorklet::postTask(ScriptState* script_state, ...@@ -55,17 +55,14 @@ Task* TaskWorklet::postTask(ScriptState* script_state,
// TODO(japhet): Here and below: it's unclear what task type should be used, // TODO(japhet): Here and below: it's unclear what task type should be used,
// and whether the API should allow it to be configured. Using kIdleTask as a // and whether the API should allow it to be configured. Using kIdleTask as a
// placeholder for now. // placeholder for now.
ThreadPoolTask* thread_pool_task = new ThreadPoolTask( return new Task(this, script_state, function, arguments, TaskType::kIdleTask);
this, script_state, function, arguments, TaskType::kIdleTask);
return new Task(thread_pool_task);
} }
Task* TaskWorklet::postTask(ScriptState* script_state, Task* TaskWorklet::postTask(ScriptState* script_state,
const String& function_name, const String& function_name,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
ThreadPoolTask* thread_pool_task = new ThreadPoolTask( return new Task(this, script_state, function_name, arguments,
this, script_state, function_name, arguments, TaskType::kIdleTask); TaskType::kIdleTask);
return new Task(thread_pool_task);
} }
ThreadPoolThread* TaskWorklet::GetLeastBusyThread() { ThreadPoolThread* TaskWorklet::GetLeastBusyThread() {
......
...@@ -39,19 +39,17 @@ WorkerTaskQueue::WorkerTaskQueue(Document* document, TaskType task_type) ...@@ -39,19 +39,17 @@ WorkerTaskQueue::WorkerTaskQueue(Document* document, TaskType task_type)
ScriptPromise WorkerTaskQueue::postFunction( ScriptPromise WorkerTaskQueue::postFunction(
ScriptState* script_state, ScriptState* script_state,
const ScriptValue& task, const ScriptValue& function,
AbortSignal* signal, AbortSignal* signal,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
DCHECK(document_->IsContextThread()); DCHECK(document_->IsContextThread());
DCHECK(task.IsFunction()); DCHECK(function.IsFunction());
ThreadPoolTask* thread_pool_task = new ThreadPoolTask( Task* task = new Task(ThreadPool::From(*document_), script_state, function,
ThreadPool::From(*document_), script_state, task, arguments, task_type_); arguments, task_type_);
if (signal) { if (signal)
signal->AddAlgorithm( signal->AddAlgorithm(WTF::Bind(&Task::cancel, WrapWeakPersistent(task)));
WTF::Bind(&ThreadPoolTask::Cancel, thread_pool_task->GetWeakPtr())); return task->result();
}
return thread_pool_task->GetResult();
} }
Task* WorkerTaskQueue::postTask(ScriptState* script_state, Task* WorkerTaskQueue::postTask(ScriptState* script_state,
...@@ -59,11 +57,8 @@ Task* WorkerTaskQueue::postTask(ScriptState* script_state, ...@@ -59,11 +57,8 @@ Task* WorkerTaskQueue::postTask(ScriptState* script_state,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
DCHECK(document_->IsContextThread()); DCHECK(document_->IsContextThread());
DCHECK(function.IsFunction()); DCHECK(function.IsFunction());
return new Task(ThreadPool::From(*document_), script_state, function,
ThreadPoolTask* thread_pool_task = arguments, task_type_);
new ThreadPoolTask(ThreadPool::From(*document_), script_state, function,
arguments, task_type_);
return new Task(thread_pool_task);
} }
void WorkerTaskQueue::Trace(blink::Visitor* visitor) { void WorkerTaskQueue::Trace(blink::Visitor* visitor) {
......
...@@ -30,12 +30,12 @@ class CORE_EXPORT WorkerTaskQueue : public ScriptWrappable { ...@@ -30,12 +30,12 @@ class CORE_EXPORT WorkerTaskQueue : public ScriptWrappable {
~WorkerTaskQueue() override = default; ~WorkerTaskQueue() override = default;
ScriptPromise postFunction(ScriptState*, ScriptPromise postFunction(ScriptState*,
const ScriptValue& task, const ScriptValue& function,
AbortSignal*, AbortSignal*,
const Vector<ScriptValue>& arguments); const Vector<ScriptValue>& arguments);
Task* postTask(ScriptState*, Task* postTask(ScriptState*,
const ScriptValue& task, const ScriptValue& function,
const Vector<ScriptValue>& arguments); const Vector<ScriptValue>& arguments);
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) 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