blob: d7d7085d945aaf2ff6cf29436b79732568b26e2d [file] [log] [blame]
// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/script/v8c/cobalt_platform.h"
#include "base/logging.h"
namespace cobalt {
namespace script {
namespace v8c {
CobaltPlatform::CobaltV8TaskRunner::CobaltV8TaskRunner()
: ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {}
void CobaltPlatform::CobaltV8TaskRunner::PostTask(
std::unique_ptr<v8::Task> task) {
PostDelayedTask(std::move(task), 0);
}
void CobaltPlatform::CobaltV8TaskRunner::PostDelayedTask(
std::unique_ptr<v8::Task> task, double delay_in_seconds) {
base::AutoLock auto_lock(lock_);
if (task_runner_) {
task_runner_->PostDelayedTask(
FROM_HERE,
base::Bind(&CobaltPlatform::CobaltV8TaskRunner::RunV8Task,
weak_ptr_factory_.GetWeakPtr(), base::Passed(&task)),
base::TimeDelta::FromSecondsD(delay_in_seconds));
} else {
tasks_before_registration_.push_back(
std::unique_ptr<TaskBeforeRegistration>(
new TaskBeforeRegistration(delay_in_seconds, std::move(task))));
}
}
void CobaltPlatform::CobaltV8TaskRunner::SetTaskRunner(
base::SingleThreadTaskRunner* task_runner) {
base::AutoLock auto_lock(lock_);
task_runner_ = task_runner;
DCHECK(task_runner);
for (unsigned int i = 0; i < tasks_before_registration_.size(); ++i) {
std::unique_ptr<v8::Task> scoped_task =
std::move(tasks_before_registration_[i]->task);
base::TimeDelta delay = std::max(
tasks_before_registration_[i]->target_time - base::TimeTicks::Now(),
base::TimeDelta::FromSeconds(0));
task_runner_->PostDelayedTask(
FROM_HERE,
base::Bind(&CobaltPlatform::CobaltV8TaskRunner::RunV8Task,
weak_ptr_factory_.GetWeakPtr(), base::Passed(&scoped_task)),
delay);
}
tasks_before_registration_.clear();
}
void CobaltPlatform::CobaltV8TaskRunner::RunV8Task(
std::unique_ptr<v8::Task> task) {
task->Run();
}
std::shared_ptr<v8::TaskRunner> CobaltPlatform::GetForegroundTaskRunner(
v8::Isolate* isolate) {
base::AutoLock auto_lock(lock_);
std::shared_ptr<CobaltPlatform::CobaltV8TaskRunner> task_runner;
if (v8_task_runner_map_.find(isolate) == v8_task_runner_map_.end()) {
task_runner = std::make_shared<CobaltPlatform::CobaltV8TaskRunner>();
v8_task_runner_map_.emplace(isolate, task_runner);
} else {
task_runner = v8_task_runner_map_[isolate];
}
DCHECK(task_runner);
return task_runner;
}
void CobaltPlatform::RegisterIsolateOnThread(v8::Isolate* isolate,
base::MessageLoop* message_loop) {
DCHECK(message_loop);
auto task_runner = GetForegroundTaskRunner(isolate);
CobaltPlatform::CobaltV8TaskRunner* cobalt_v8_task_runner =
base::polymorphic_downcast<CobaltPlatform::CobaltV8TaskRunner*>(
task_runner.get());
cobalt_v8_task_runner->SetTaskRunner(message_loop->task_runner().get());
}
void CobaltPlatform::UnregisterIsolateOnThread(v8::Isolate* isolate) {
base::AutoLock auto_lock(lock_);
auto iter = v8_task_runner_map_.find(isolate);
if (iter != v8_task_runner_map_.end()) {
v8_task_runner_map_.erase(iter);
} else {
DLOG(WARNING) << "Isolate is not in the map and can not be unregistered.";
}
}
void CobaltPlatform::CallOnForegroundThread(v8::Isolate* isolate,
v8::Task* task) {
GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<v8::Task>(task));
}
void CobaltPlatform::CallDelayedOnForegroundThread(v8::Isolate* isolate,
v8::Task* task,
double delay_in_seconds) {
GetForegroundTaskRunner(isolate)->PostDelayedTask(
std::unique_ptr<v8::Task>(task), delay_in_seconds);
}
} // namespace v8c
} // namespace script
} // namespace cobalt