src: use unique_ptr for scheduled delayed tasks
Use std::unique_ptr for delayed tasks in the scheduled delayed tasks vector. This makes it clear that the vector has ownership of the delayed tasks and is responsible for deleting them. Use a custom deleter for the pointers because libuv needs to close the handle and then delete the data. Provide the handle when creating the pointer instead of invoking the special delete action everytime an element is removed from the vector. PR-URL: https://github.com/nodejs/node/pull/17083 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
f841fc63dd
commit
24e824ad68
@ -134,26 +134,23 @@ void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr<Task> 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<DelayedTask*>(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<uv_handle_t*>(&delayed->timer),
|
||||
[](uv_handle_t* handle) {
|
||||
delete static_cast<DelayedTask*>(handle->data);
|
||||
});
|
||||
delayed->platform_data->DeleteFromScheduledTasks(delayed);
|
||||
}
|
||||
|
||||
void PerIsolatePlatformData::CancelPendingDelayedTasks() {
|
||||
for (auto delayed : scheduled_delayed_tasks_) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&delayed->timer),
|
||||
[](uv_handle_t* handle) {
|
||||
delete static_cast<DelayedTask*>(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<uv_handle_t*>(&delayed->timer));
|
||||
scheduled_delayed_tasks_.push_back(delayed.release());
|
||||
|
||||
scheduled_delayed_tasks_.emplace_back(delayed.release(),
|
||||
[](DelayedTask* delayed) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&delayed->timer),
|
||||
[](uv_handle_t* handle) {
|
||||
delete static_cast<DelayedTask*>(handle->data);
|
||||
});
|
||||
});
|
||||
}
|
||||
while (std::unique_ptr<Task> task = foreground_tasks_.Pop()) {
|
||||
did_work = true;
|
||||
|
@ -64,6 +64,8 @@ class PerIsolatePlatformData {
|
||||
void CancelPendingDelayedTasks();
|
||||
|
||||
private:
|
||||
void DeleteFromScheduledTasks(DelayedTask* task);
|
||||
|
||||
static void FlushTasks(uv_async_t* handle);
|
||||
static void RunForegroundTask(std::unique_ptr<v8::Task> task);
|
||||
static void RunForegroundTask(uv_timer_t* timer);
|
||||
@ -74,7 +76,11 @@ class PerIsolatePlatformData {
|
||||
uv_async_t* flush_tasks_ = nullptr;
|
||||
TaskQueue<v8::Task> foreground_tasks_;
|
||||
TaskQueue<DelayedTask> foreground_delayed_tasks_;
|
||||
std::vector<DelayedTask*> scheduled_delayed_tasks_;
|
||||
|
||||
// Use a custom deleter because libuv needs to close the handle first.
|
||||
typedef std::unique_ptr<DelayedTask, std::function<void(DelayedTask*)>>
|
||||
DelayedTaskPointer;
|
||||
std::vector<DelayedTaskPointer> scheduled_delayed_tasks_;
|
||||
};
|
||||
|
||||
class NodePlatform : public MultiIsolatePlatform {
|
||||
|
Loading…
x
Reference in New Issue
Block a user