summaryrefslogtreecommitdiff
path: root/src/node_platform.h
diff options
context:
space:
mode:
authorMatt Loring <mattloring@google.com>2017-03-13 15:17:57 -0700
committerAnna Henningsen <anna@addaleax.net>2017-08-17 20:26:55 +0200
commit9e08695f85d4273f01e010cf384f42030d66b453 (patch)
tree24e9bc7ba9c4e2784cb18b3d692ef227b9de4e28 /src/node_platform.h
parent5e5a52fc937d53b5bcf5c2c09c898d8311db2bca (diff)
downloadandroid-node-v8-9e08695f85d4273f01e010cf384f42030d66b453.tar.gz
android-node-v8-9e08695f85d4273f01e010cf384f42030d66b453.tar.bz2
android-node-v8-9e08695f85d4273f01e010cf384f42030d66b453.zip
src: Node implementation of v8::Platform
Node.js currently uses the V8 implementation of the DefaultPlatform which schedules VM tasks on a V8 managed thread pool. Since the Node.js event loop is not aware of these tasks, the Node.js process may exit while there are outstanding VM tasks. This will become problematic once asynchronous wasm compilation lands in V8. This PR introduces a Node.js specific implementation of the v8::Platform on top of libuv so that the event loop is aware of outstanding VM tasks. PR-URL: https://github.com/nodejs/node/pull/14001 Fixes: https://github.com/nodejs/node/issues/3665 Fixes: https://github.com/nodejs/node/issues/8496 Fixes: https://github.com/nodejs/node/issues/12980 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Diffstat (limited to 'src/node_platform.h')
-rw-r--r--src/node_platform.h69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/node_platform.h b/src/node_platform.h
new file mode 100644
index 0000000000..668fcf28e4
--- /dev/null
+++ b/src/node_platform.h
@@ -0,0 +1,69 @@
+#ifndef SRC_NODE_PLATFORM_H_
+#define SRC_NODE_PLATFORM_H_
+
+#include <queue>
+#include <vector>
+
+#include "libplatform/libplatform.h"
+#include "node_mutex.h"
+#include "uv.h"
+
+namespace node {
+
+template <class T>
+class TaskQueue {
+ public:
+ TaskQueue();
+ ~TaskQueue() {}
+
+ void Push(T* task);
+ T* Pop();
+ T* BlockingPop();
+ void NotifyOfCompletion();
+ void BlockingDrain();
+ void Stop();
+
+ private:
+ Mutex lock_;
+ ConditionVariable tasks_available_;
+ ConditionVariable tasks_drained_;
+ int outstanding_tasks_;
+ bool stopped_;
+ std::queue<T*> task_queue_;
+};
+
+class NodePlatform : public v8::Platform {
+ public:
+ NodePlatform(int thread_pool_size, uv_loop_t* loop,
+ v8::TracingController* tracing_controller);
+ virtual ~NodePlatform() {}
+
+ void DrainBackgroundTasks();
+ void FlushForegroundTasksInternal();
+ void Shutdown();
+
+ // v8::Platform implementation.
+ size_t NumberOfAvailableBackgroundThreads() override;
+ void CallOnBackgroundThread(v8::Task* task,
+ ExpectedRuntime expected_runtime) override;
+ void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override;
+ void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
+ double delay_in_seconds) override;
+ bool IdleTasksEnabled(v8::Isolate* isolate) override;
+ double MonotonicallyIncreasingTime() override;
+ v8::TracingController* GetTracingController() override;
+
+ private:
+ uv_loop_t* const loop_;
+ uv_async_t flush_tasks_;
+ TaskQueue<v8::Task> foreground_tasks_;
+ TaskQueue<std::pair<v8::Task*, double>> foreground_delayed_tasks_;
+ TaskQueue<v8::Task> background_tasks_;
+ std::vector<std::unique_ptr<uv_thread_t>> threads_;
+
+ std::unique_ptr<v8::TracingController> tracing_controller_;
+};
+
+} // namespace node
+
+#endif // SRC_NODE_PLATFORM_H_