summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcel Laverdet <marcel@laverdet.com>2019-11-12 14:26:08 -0800
committerAnna Henningsen <anna@addaleax.net>2019-11-20 19:02:55 +0100
commitc712fb7cd6222018cf615fd0071998bde6f16da9 (patch)
tree2f6713dc39dfea54e6fb6b1a56a82c9da64469a6 /src
parentc63af4fea041673eb7c33f6df3c474d4537fe5eb (diff)
downloadandroid-node-v8-c712fb7cd6222018cf615fd0071998bde6f16da9.tar.gz
android-node-v8-c712fb7cd6222018cf615fd0071998bde6f16da9.tar.bz2
android-node-v8-c712fb7cd6222018cf615fd0071998bde6f16da9.zip
src: add abstract `IsolatePlatformDelegate`
Adds a new abstract class for module authors and embedders to register arbitrary isolates with `node::MultiIsolatePlatform`. PR-URL: https://github.com/nodejs/node/pull/30324 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/node.h12
-rw-r--r--src/node_platform.cc66
-rw-r--r--src/node_platform.h13
3 files changed, 69 insertions, 22 deletions
diff --git a/src/node.h b/src/node.h
index c80e626685..f3da457401 100644
--- a/src/node.h
+++ b/src/node.h
@@ -262,6 +262,12 @@ class NODE_EXTERN ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator();
NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator);
+class NODE_EXTERN IsolatePlatformDelegate {
+ public:
+ virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() = 0;
+ virtual bool IdleTasksEnabled() = 0;
+};
+
class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
public:
~MultiIsolatePlatform() override = default;
@@ -283,6 +289,12 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
// This function may only be called once per `Isolate`.
virtual void RegisterIsolate(v8::Isolate* isolate,
struct uv_loop_s* loop) = 0;
+ // This method can be used when an application handles task scheduling on its
+ // own through `IsolatePlatformDelegate`. Upon registering an isolate with
+ // this overload any other method in this class with the exception of
+ // `UnregisterIsolate` *must not* be used on that isolate.
+ virtual void RegisterIsolate(v8::Isolate* isolate,
+ IsolatePlatformDelegate* delegate) = 0;
// This function may only be called once per `Isolate`, and discard any
// pending delayed tasks scheduled for that isolate.
diff --git a/src/node_platform.cc b/src/node_platform.cc
index 6e3b4abfee..383f67ce0f 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -230,6 +230,11 @@ PerIsolatePlatformData::PerIsolatePlatformData(
uv_unref(reinterpret_cast<uv_handle_t*>(flush_tasks_));
}
+std::shared_ptr<v8::TaskRunner>
+PerIsolatePlatformData::GetForegroundTaskRunner() {
+ return shared_from_this();
+}
+
void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
auto platform_data = static_cast<PerIsolatePlatformData*>(handle->data);
platform_data->FlushForegroundTasksInternal();
@@ -267,7 +272,7 @@ void PerIsolatePlatformData::PostNonNestableDelayedTask(
}
PerIsolatePlatformData::~PerIsolatePlatformData() {
- Shutdown();
+ CHECK(!flush_tasks_);
}
void PerIsolatePlatformData::AddShutdownCallback(void (*callback)(void*),
@@ -325,18 +330,32 @@ NodePlatform::NodePlatform(int thread_pool_size,
void NodePlatform::RegisterIsolate(Isolate* isolate, uv_loop_t* loop) {
Mutex::ScopedLock lock(per_isolate_mutex_);
- std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate];
- CHECK(!existing);
- per_isolate_[isolate] =
- std::make_shared<PerIsolatePlatformData>(isolate, loop);
+ auto delegate = std::make_shared<PerIsolatePlatformData>(isolate, loop);
+ IsolatePlatformDelegate* ptr = delegate.get();
+ auto insertion = per_isolate_.emplace(
+ isolate,
+ std::make_pair(ptr, std::move(delegate)));
+ CHECK(insertion.second);
+}
+
+void NodePlatform::RegisterIsolate(Isolate* isolate,
+ IsolatePlatformDelegate* delegate) {
+ Mutex::ScopedLock lock(per_isolate_mutex_);
+ auto insertion = per_isolate_.emplace(
+ isolate,
+ std::make_pair(delegate, std::shared_ptr<PerIsolatePlatformData>{}));
+ CHECK(insertion.second);
}
void NodePlatform::UnregisterIsolate(Isolate* isolate) {
Mutex::ScopedLock lock(per_isolate_mutex_);
- std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate];
- CHECK(existing);
- existing->Shutdown();
- per_isolate_.erase(isolate);
+ auto existing_it = per_isolate_.find(isolate);
+ CHECK_NE(existing_it, per_isolate_.end());
+ auto& existing = existing_it->second;
+ if (existing.second) {
+ existing.second->Shutdown();
+ }
+ per_isolate_.erase(existing_it);
}
void NodePlatform::AddIsolateFinishedCallback(Isolate* isolate,
@@ -344,11 +363,11 @@ void NodePlatform::AddIsolateFinishedCallback(Isolate* isolate,
Mutex::ScopedLock lock(per_isolate_mutex_);
auto it = per_isolate_.find(isolate);
if (it == per_isolate_.end()) {
- CHECK(it->second);
cb(data);
return;
}
- it->second->AddShutdownCallback(cb, data);
+ CHECK(it->second.second);
+ it->second.second->AddShutdownCallback(cb, data);
}
void NodePlatform::Shutdown() {
@@ -394,7 +413,7 @@ void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) {
}
void NodePlatform::DrainTasks(Isolate* isolate) {
- std::shared_ptr<PerIsolatePlatformData> per_isolate = ForIsolate(isolate);
+ std::shared_ptr<PerIsolatePlatformData> per_isolate = ForNodeIsolate(isolate);
do {
// Worker tasks aren't associated with an Isolate.
@@ -452,23 +471,32 @@ void NodePlatform::CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
}
+IsolatePlatformDelegate* NodePlatform::ForIsolate(Isolate* isolate) {
+ Mutex::ScopedLock lock(per_isolate_mutex_);
+ auto data = per_isolate_[isolate];
+ CHECK_NOT_NULL(data.first);
+ return data.first;
+}
+
std::shared_ptr<PerIsolatePlatformData>
-NodePlatform::ForIsolate(Isolate* isolate) {
+NodePlatform::ForNodeIsolate(Isolate* isolate) {
Mutex::ScopedLock lock(per_isolate_mutex_);
- std::shared_ptr<PerIsolatePlatformData> data = per_isolate_[isolate];
- CHECK(data);
- return data;
+ auto data = per_isolate_[isolate];
+ CHECK(data.second);
+ return data.second;
}
bool NodePlatform::FlushForegroundTasks(Isolate* isolate) {
- return ForIsolate(isolate)->FlushForegroundTasksInternal();
+ return ForNodeIsolate(isolate)->FlushForegroundTasksInternal();
}
-bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; }
+bool NodePlatform::IdleTasksEnabled(Isolate* isolate) {
+ return ForIsolate(isolate)->IdleTasksEnabled();
+}
std::shared_ptr<v8::TaskRunner>
NodePlatform::GetForegroundTaskRunner(Isolate* isolate) {
- return ForIsolate(isolate);
+ return ForIsolate(isolate)->GetForegroundTaskRunner();
}
double NodePlatform::MonotonicallyIncreasingTime() {
diff --git a/src/node_platform.h b/src/node_platform.h
index 24f7b337bb..e47d72b366 100644
--- a/src/node_platform.h
+++ b/src/node_platform.h
@@ -52,12 +52,14 @@ struct DelayedTask {
// This acts as the foreground task runner for a given Isolate.
class PerIsolatePlatformData :
+ public IsolatePlatformDelegate,
public v8::TaskRunner,
public std::enable_shared_from_this<PerIsolatePlatformData> {
public:
PerIsolatePlatformData(v8::Isolate* isolate, uv_loop_t* loop);
~PerIsolatePlatformData() override;
+ std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() override;
void PostTask(std::unique_ptr<v8::Task> task) override;
void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
void PostDelayedTask(std::unique_ptr<v8::Task> task,
@@ -162,6 +164,9 @@ class NodePlatform : public MultiIsolatePlatform {
bool FlushForegroundTasks(v8::Isolate* isolate) override;
void RegisterIsolate(v8::Isolate* isolate, uv_loop_t* loop) override;
+ void RegisterIsolate(v8::Isolate* isolate,
+ IsolatePlatformDelegate* delegate) override;
+
void UnregisterIsolate(v8::Isolate* isolate) override;
void AddIsolateFinishedCallback(v8::Isolate* isolate,
void (*callback)(void*), void* data) override;
@@ -170,11 +175,13 @@ class NodePlatform : public MultiIsolatePlatform {
v8::Isolate* isolate) override;
private:
- std::shared_ptr<PerIsolatePlatformData> ForIsolate(v8::Isolate* isolate);
+ IsolatePlatformDelegate* ForIsolate(v8::Isolate* isolate);
+ std::shared_ptr<PerIsolatePlatformData> ForNodeIsolate(v8::Isolate* isolate);
Mutex per_isolate_mutex_;
- std::unordered_map<v8::Isolate*,
- std::shared_ptr<PerIsolatePlatformData>> per_isolate_;
+ using DelegatePair = std::pair<
+ IsolatePlatformDelegate*, std::shared_ptr<PerIsolatePlatformData>>;
+ std::unordered_map<v8::Isolate*, DelegatePair> per_isolate_;
node::tracing::TracingController* tracing_controller_;
std::shared_ptr<WorkerThreadsTaskRunner> worker_thread_task_runner_;