summaryrefslogtreecommitdiff
path: root/src/node_platform.cc
diff options
context:
space:
mode:
authorUlan Degenbaev <ulan@chromium.org>2018-04-12 22:01:11 +0200
committerAnatoli Papirovski <apapirovski@mac.com>2018-04-25 10:40:16 +0200
commitd3edf2fcde0c37206dc339aab7333212d20aa0f1 (patch)
treefaf96de3d8b841f6dda9f7b0a049c67289862659 /src/node_platform.cc
parent95197ed2b052b1fee312cfc127a9f67844dd77b7 (diff)
downloadandroid-node-v8-d3edf2fcde0c37206dc339aab7333212d20aa0f1.tar.gz
android-node-v8-d3edf2fcde0c37206dc339aab7333212d20aa0f1.tar.bz2
android-node-v8-d3edf2fcde0c37206dc339aab7333212d20aa0f1.zip
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 d96db08692..b8f1344727 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