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:
authorUlan Degenbaev <ulan@chromium.org>2018-04-12 23:01:11 +0300
committerAnatoli Papirovski <apapirovski@mac.com>2018-04-25 11:40:16 +0300
commitd3edf2fcde0c37206dc339aab7333212d20aa0f1 (patch)
treefaf96de3d8b841f6dda9f7b0a049c67289862659 /src/node_platform.cc
parent95197ed2b052b1fee312cfc127a9f67844dd77b7 (diff)
src: limit foreground tasks draining loop
Foreground tasks that repost themselves can force the draining loop to run indefinitely long without giving other tasks chance to run. This limits the foreground task draining loop to run only the tasks that were in the tasks queue at the beginning of the loop. PR-URL: https://github.com/nodejs/node/pull/19987 Fixes: https://github.com/nodejs/node/issues/19937 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yang Guo <yangguo@chromium.org> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Khaidi Chu <i@2333.moe>
Diffstat (limited to 'src/node_platform.cc')
-rw-r--r--src/node_platform.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/node_platform.cc b/src/node_platform.cc
index d96db086925..b8f1344727c 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -95,7 +95,7 @@ void PerIsolatePlatformData::PostDelayedTask(
}
PerIsolatePlatformData::~PerIsolatePlatformData() {
- FlushForegroundTasksInternal();
+ while (FlushForegroundTasksInternal()) {}
CancelPendingDelayedTasks();
uv_close(reinterpret_cast<uv_handle_t*>(flush_tasks_),
@@ -223,7 +223,13 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
});
});
}
- while (std::unique_ptr<Task> task = foreground_tasks_.Pop()) {
+ // Move all foreground tasks into a separate queue and flush that queue.
+ // This way tasks that are posted while flushing the queue will be run on the
+ // next call of FlushForegroundTasksInternal.
+ std::queue<std::unique_ptr<Task>> tasks = foreground_tasks_.PopAll();
+ while (!tasks.empty()) {
+ std::unique_ptr<Task> task = std::move(tasks.front());
+ tasks.pop();
did_work = true;
RunForegroundTask(std::move(task));
}
@@ -254,8 +260,8 @@ void NodePlatform::CallDelayedOnForegroundThread(Isolate* isolate,
std::unique_ptr<Task>(task), delay_in_seconds);
}
-void NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) {
- ForIsolate(isolate)->FlushForegroundTasksInternal();
+bool NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) {
+ return ForIsolate(isolate)->FlushForegroundTasksInternal();
}
void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) {
@@ -348,4 +354,12 @@ void TaskQueue<T>::Stop() {
tasks_available_.Broadcast(scoped_lock);
}
+template <class T>
+std::queue<std::unique_ptr<T>> TaskQueue<T>::PopAll() {
+ Mutex::ScopedLock scoped_lock(lock_);
+ std::queue<std::unique_ptr<T>> result;
+ result.swap(task_queue_);
+ return result;
+}
+
} // namespace node