diff --git a/src/node_platform.cc b/src/node_platform.cc index 2deccdcdf68..5f320bd7924 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -159,7 +159,9 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler { // ScheduleTasks (start a timer that pops the task into the worker queue) // in posting order, then, once Stop() was called, the StopTask. - for (std::unique_ptr& task : scheduler->tasks_.Lock().PopAll()) { + std::vector> tasks = + scheduler->tasks_.Lock().PopAll(); + for (std::unique_ptr& task : tasks) { task->Run(); } } @@ -605,8 +607,9 @@ void NodePlatform::DrainTasks(Isolate* isolate) { bool PerIsolatePlatformData::FlushForegroundTasksInternal() { bool did_work = false; - for (std::unique_ptr& delayed : - foreground_delayed_tasks_.Lock().PopAll()) { + std::vector> delayed_tasks = + foreground_delayed_tasks_.Lock().PopAll(); + for (std::unique_ptr& delayed : delayed_tasks) { did_work = true; uint64_t delay_millis = llround(delayed->timeout * 1000); @@ -629,8 +632,9 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() { }); } - for (std::unique_ptr& entry : - foreground_tasks_.Lock().PopAll()) { + std::vector> tasks = + foreground_tasks_.Lock().PopAll(); + for (std::unique_ptr& entry : tasks) { did_work = true; RunForegroundTask(std::move(entry->task)); } diff --git a/src/node_platform.h b/src/node_platform.h index bd6fe024d5e..52e3e629bc0 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -35,7 +35,9 @@ class TaskQueue { void NotifyOfOutstandingCompletion(); void BlockingDrain(); void Stop(); - // All queued tasks, in the order Pop() would have returned them. + // All queued tasks, in the order Pop() would have returned them. Store the + // result before iterating it: used directly as a range-for initializer, + // `Lock().PopAll()` keeps the lock held for the whole loop from C++23 on. std::vector> PopAll(); private: