diff --git a/src/node_platform.cc b/src/node_platform.cc index 51927cf7f9f792..0c50e8468d0f44 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -134,26 +134,23 @@ void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr task) { task->Run(); } +void PerIsolatePlatformData::DeleteFromScheduledTasks(DelayedTask* task) { + auto it = std::find_if(scheduled_delayed_tasks_.begin(), + scheduled_delayed_tasks_.end(), + [task](const DelayedTaskPointer& delayed) -> bool { + return delayed.get() == task; + }); + CHECK_NE(it, scheduled_delayed_tasks_.end()); + scheduled_delayed_tasks_.erase(it); +} + void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) { DelayedTask* delayed = static_cast(handle->data); - auto& tasklist = delayed->platform_data->scheduled_delayed_tasks_; - auto it = std::find(tasklist.begin(), tasklist.end(), delayed); - CHECK_NE(it, tasklist.end()); - tasklist.erase(it); RunForegroundTask(std::move(delayed->task)); - uv_close(reinterpret_cast(&delayed->timer), - [](uv_handle_t* handle) { - delete static_cast(handle->data); - }); + delayed->platform_data->DeleteFromScheduledTasks(delayed); } void PerIsolatePlatformData::CancelPendingDelayedTasks() { - for (auto delayed : scheduled_delayed_tasks_) { - uv_close(reinterpret_cast(&delayed->timer), - [](uv_handle_t* handle) { - delete static_cast(handle->data); - }); - } scheduled_delayed_tasks_.clear(); } @@ -183,7 +180,14 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() { // the delay is non-zero. This should not be a problem in practice. uv_timer_start(&delayed->timer, RunForegroundTask, delay_millis, 0); uv_unref(reinterpret_cast(&delayed->timer)); - scheduled_delayed_tasks_.push_back(delayed.release()); + + scheduled_delayed_tasks_.emplace_back(delayed.release(), + [](DelayedTask* delayed) { + uv_close(reinterpret_cast(&delayed->timer), + [](uv_handle_t* handle) { + delete static_cast(handle->data); + }); + }); } while (std::unique_ptr task = foreground_tasks_.Pop()) { did_work = true; diff --git a/src/node_platform.h b/src/node_platform.h index 584506ae1f114a..48301a05a11d8c 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "libplatform/libplatform.h" #include "node.h" @@ -64,6 +65,8 @@ class PerIsolatePlatformData { void CancelPendingDelayedTasks(); private: + void DeleteFromScheduledTasks(DelayedTask* task); + static void FlushTasks(uv_async_t* handle); static void RunForegroundTask(std::unique_ptr task); static void RunForegroundTask(uv_timer_t* timer); @@ -74,7 +77,11 @@ class PerIsolatePlatformData { uv_async_t* flush_tasks_ = nullptr; TaskQueue foreground_tasks_; TaskQueue foreground_delayed_tasks_; - std::vector scheduled_delayed_tasks_; + + // Use a custom deleter because libuv needs to close the handle first. + typedef std::unique_ptr> + DelayedTaskPointer; + std::vector scheduled_delayed_tasks_; }; class NodePlatform : public MultiIsolatePlatform {