Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2017-09-15 16:03:48 +0300
committerAnna Henningsen <anna@addaleax.net>2017-09-21 03:03:02 +0300
commitf27b5e4bdaafc73a830a0451ee3c641b8bcd08fe (patch)
tree09e8fccc815d2a27db433ce233e80bbcbeb0579a /src/node_platform.cc
parent01c680b92aed62e128aa2abd4ad923f9a6a0331a (diff)
src: prepare platform for upstream V8 changes
V8 platform tasks may schedule other tasks (both background and foreground), and may perform asynchronous operations like resolving Promises. To address that: - Run the task queue drain call inside a callback scope. This makes sure asynchronous operations inside it, like resolving promises, lead to the microtask queue and any subsequent operations not being silently forgotten. - Move the task queue drain call before `EmitBeforeExit()` and only run `EmitBeforeExit()` if there is no new event loop work. - Account for possible new foreground tasks scheduled by background tasks in `DrainBackgroundTasks()`. PR-URL: https://github.com/nodejs/node/pull/15428 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Matthew Loring <mattloring@google.com>
Diffstat (limited to 'src/node_platform.cc')
-rw-r--r--src/node_platform.cc30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/node_platform.cc b/src/node_platform.cc
index 3d023114ad2..320136c3f72 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -1,10 +1,14 @@
#include "node_platform.h"
+#include "node_internals.h"
#include "util.h"
namespace node {
+using v8::HandleScope;
using v8::Isolate;
+using v8::Local;
+using v8::Object;
using v8::Platform;
using v8::Task;
using v8::TracingController;
@@ -63,22 +67,33 @@ size_t NodePlatform::NumberOfAvailableBackgroundThreads() {
return threads_.size();
}
-static void RunForegroundTask(uv_timer_t* handle) {
- Task* task = static_cast<Task*>(handle->data);
+static void RunForegroundTask(Task* task) {
+ Isolate* isolate = Isolate::GetCurrent();
+ HandleScope scope(isolate);
+ Environment* env = Environment::GetCurrent(isolate);
+ InternalCallbackScope cb_scope(env, Local<Object>(), { 0, 0 },
+ InternalCallbackScope::kAllowEmptyResource);
task->Run();
delete task;
+}
+
+static void RunForegroundTask(uv_timer_t* handle) {
+ Task* task = static_cast<Task*>(handle->data);
+ RunForegroundTask(task);
uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
delete reinterpret_cast<uv_timer_t*>(handle);
});
}
void NodePlatform::DrainBackgroundTasks() {
- FlushForegroundTasksInternal();
- background_tasks_.BlockingDrain();
+ while (FlushForegroundTasksInternal())
+ background_tasks_.BlockingDrain();
}
-void NodePlatform::FlushForegroundTasksInternal() {
+bool NodePlatform::FlushForegroundTasksInternal() {
+ bool did_work = false;
while (auto delayed = foreground_delayed_tasks_.Pop()) {
+ did_work = true;
uint64_t delay_millis =
static_cast<uint64_t>(delayed->second + 0.5) * 1000;
uv_timer_t* handle = new uv_timer_t();
@@ -91,9 +106,10 @@ void NodePlatform::FlushForegroundTasksInternal() {
delete delayed;
}
while (Task* task = foreground_tasks_.Pop()) {
- task->Run();
- delete task;
+ did_work = true;
+ RunForegroundTask(task);
}
+ return did_work;
}
void NodePlatform::CallOnBackgroundThread(Task* task,