Skip to content

Commit 8522e24

Browse files
fhinkelMylesBorins
authored andcommitted
src: use unique_ptr in platform implementation
Replace raw pointers in task queues with std::unique_ptr. This makes ownership obvious. PR-URL: #16970 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Gireesh Punathil <[email protected]>
1 parent c2431d5 commit 8522e24

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

src/node_platform.cc

+34-34
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ using v8::TracingController;
1818

1919
static void BackgroundRunner(void* data) {
2020
TaskQueue<Task>* background_tasks = static_cast<TaskQueue<Task>*>(data);
21-
while (Task* task = background_tasks->BlockingPop()) {
21+
while (std::unique_ptr<Task> task = background_tasks->BlockingPop()) {
2222
task->Run();
23-
delete task;
2423
background_tasks->NotifyOfCompletion();
2524
}
2625
}
@@ -39,18 +38,19 @@ void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
3938
platform_data->FlushForegroundTasksInternal();
4039
}
4140

42-
void PerIsolatePlatformData::CallOnForegroundThread(Task* task) {
43-
foreground_tasks_.Push(task);
41+
void PerIsolatePlatformData::CallOnForegroundThread(
42+
std::unique_ptr<Task> task) {
43+
foreground_tasks_.Push(std::move(task));
4444
uv_async_send(flush_tasks_);
4545
}
4646

4747
void PerIsolatePlatformData::CallDelayedOnForegroundThread(
48-
Task* task, double delay_in_seconds) {
49-
auto delayed = new DelayedTask();
50-
delayed->task = task;
48+
std::unique_ptr<Task> task, double delay_in_seconds) {
49+
std::unique_ptr<DelayedTask> delayed(new DelayedTask());
50+
delayed->task = std::move(task);
5151
delayed->platform_data = this;
5252
delayed->timeout = delay_in_seconds;
53-
foreground_delayed_tasks_.Push(delayed);
53+
foreground_delayed_tasks_.Push(std::move(delayed));
5454
uv_async_send(flush_tasks_);
5555
}
5656

@@ -125,14 +125,13 @@ size_t NodePlatform::NumberOfAvailableBackgroundThreads() {
125125
return threads_.size();
126126
}
127127

128-
void PerIsolatePlatformData::RunForegroundTask(Task* task) {
128+
void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr<Task> task) {
129129
Isolate* isolate = Isolate::GetCurrent();
130130
HandleScope scope(isolate);
131131
Environment* env = Environment::GetCurrent(isolate);
132132
InternalCallbackScope cb_scope(env, Local<Object>(), { 0, 0 },
133133
InternalCallbackScope::kAllowEmptyResource);
134134
task->Run();
135-
delete task;
136135
}
137136

138137
void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) {
@@ -141,7 +140,7 @@ void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) {
141140
auto it = std::find(tasklist.begin(), tasklist.end(), delayed);
142141
CHECK_NE(it, tasklist.end());
143142
tasklist.erase(it);
144-
RunForegroundTask(delayed->task);
143+
RunForegroundTask(std::move(delayed->task));
145144
uv_close(reinterpret_cast<uv_handle_t*>(&delayed->timer),
146145
[](uv_handle_t* handle) {
147146
delete static_cast<DelayedTask*>(handle->data);
@@ -162,39 +161,40 @@ void NodePlatform::DrainBackgroundTasks(Isolate* isolate) {
162161
PerIsolatePlatformData* per_isolate = ForIsolate(isolate);
163162

164163
do {
165-
// Right now, there is no way to drain only background tasks associated with
166-
// a specific isolate, so this sometimes does more work than necessary.
167-
// In the long run, that functionality is probably going to be available
168-
// anyway, though.
164+
// Right now, there is no way to drain only background tasks associated
165+
// with a specific isolate, so this sometimes does more work than
166+
// necessary. In the long run, that functionality is probably going to
167+
// be available anyway, though.
169168
background_tasks_.BlockingDrain();
170169
} while (per_isolate->FlushForegroundTasksInternal());
171170
}
172171

173172
bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
174173
bool did_work = false;
175174

176-
while (auto delayed = foreground_delayed_tasks_.Pop()) {
175+
while (std::unique_ptr<DelayedTask> delayed =
176+
foreground_delayed_tasks_.Pop()) {
177177
did_work = true;
178178
uint64_t delay_millis =
179179
static_cast<uint64_t>(delayed->timeout + 0.5) * 1000;
180-
delayed->timer.data = static_cast<void*>(delayed);
180+
delayed->timer.data = static_cast<void*>(delayed.get());
181181
uv_timer_init(loop_, &delayed->timer);
182182
// Timers may not guarantee queue ordering of events with the same delay if
183183
// the delay is non-zero. This should not be a problem in practice.
184184
uv_timer_start(&delayed->timer, RunForegroundTask, delay_millis, 0);
185185
uv_unref(reinterpret_cast<uv_handle_t*>(&delayed->timer));
186-
scheduled_delayed_tasks_.push_back(delayed);
186+
scheduled_delayed_tasks_.push_back(delayed.release());
187187
}
188-
while (Task* task = foreground_tasks_.Pop()) {
188+
while (std::unique_ptr<Task> task = foreground_tasks_.Pop()) {
189189
did_work = true;
190-
RunForegroundTask(task);
190+
RunForegroundTask(std::move(task));
191191
}
192192
return did_work;
193193
}
194194

195195
void NodePlatform::CallOnBackgroundThread(Task* task,
196196
ExpectedRuntime expected_runtime) {
197-
background_tasks_.Push(task);
197+
background_tasks_.Push(std::unique_ptr<Task>(task));
198198
}
199199

200200
PerIsolatePlatformData* NodePlatform::ForIsolate(Isolate* isolate) {
@@ -205,14 +205,14 @@ PerIsolatePlatformData* NodePlatform::ForIsolate(Isolate* isolate) {
205205
}
206206

207207
void NodePlatform::CallOnForegroundThread(Isolate* isolate, Task* task) {
208-
ForIsolate(isolate)->CallOnForegroundThread(task);
208+
ForIsolate(isolate)->CallOnForegroundThread(std::unique_ptr<Task>(task));
209209
}
210210

211211
void NodePlatform::CallDelayedOnForegroundThread(Isolate* isolate,
212212
Task* task,
213213
double delay_in_seconds) {
214-
ForIsolate(isolate)->CallDelayedOnForegroundThread(task,
215-
delay_in_seconds);
214+
ForIsolate(isolate)->CallDelayedOnForegroundThread(
215+
std::unique_ptr<Task>(task), delay_in_seconds);
216216
}
217217

218218
void NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) {
@@ -240,34 +240,34 @@ TaskQueue<T>::TaskQueue()
240240
outstanding_tasks_(0), stopped_(false), task_queue_() { }
241241

242242
template <class T>
243-
void TaskQueue<T>::Push(T* task) {
243+
void TaskQueue<T>::Push(std::unique_ptr<T> task) {
244244
Mutex::ScopedLock scoped_lock(lock_);
245245
outstanding_tasks_++;
246-
task_queue_.push(task);
246+
task_queue_.push(std::move(task));
247247
tasks_available_.Signal(scoped_lock);
248248
}
249249

250250
template <class T>
251-
T* TaskQueue<T>::Pop() {
251+
std::unique_ptr<T> TaskQueue<T>::Pop() {
252252
Mutex::ScopedLock scoped_lock(lock_);
253-
T* result = nullptr;
254-
if (!task_queue_.empty()) {
255-
result = task_queue_.front();
256-
task_queue_.pop();
253+
if (task_queue_.empty()) {
254+
return std::unique_ptr<T>(nullptr);
257255
}
256+
std::unique_ptr<T> result = std::move(task_queue_.front());
257+
task_queue_.pop();
258258
return result;
259259
}
260260

261261
template <class T>
262-
T* TaskQueue<T>::BlockingPop() {
262+
std::unique_ptr<T> TaskQueue<T>::BlockingPop() {
263263
Mutex::ScopedLock scoped_lock(lock_);
264264
while (task_queue_.empty() && !stopped_) {
265265
tasks_available_.Wait(scoped_lock);
266266
}
267267
if (stopped_) {
268-
return nullptr;
268+
return std::unique_ptr<T>(nullptr);
269269
}
270-
T* result = task_queue_.front();
270+
std::unique_ptr<T> result = std::move(task_queue_.front());
271271
task_queue_.pop();
272272
return result;
273273
}

src/node_platform.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class TaskQueue {
2222
TaskQueue();
2323
~TaskQueue() {}
2424

25-
void Push(T* task);
26-
T* Pop();
27-
T* BlockingPop();
25+
void Push(std::unique_ptr<T> task);
26+
std::unique_ptr<T> Pop();
27+
std::unique_ptr<T> BlockingPop();
2828
void NotifyOfCompletion();
2929
void BlockingDrain();
3030
void Stop();
@@ -35,11 +35,11 @@ class TaskQueue {
3535
ConditionVariable tasks_drained_;
3636
int outstanding_tasks_;
3737
bool stopped_;
38-
std::queue<T*> task_queue_;
38+
std::queue<std::unique_ptr<T>> task_queue_;
3939
};
4040

4141
struct DelayedTask {
42-
v8::Task* task;
42+
std::unique_ptr<v8::Task> task;
4343
uv_timer_t timer;
4444
double timeout;
4545
PerIsolatePlatformData* platform_data;
@@ -50,8 +50,9 @@ class PerIsolatePlatformData {
5050
PerIsolatePlatformData(v8::Isolate* isolate, uv_loop_t* loop);
5151
~PerIsolatePlatformData();
5252

53-
void CallOnForegroundThread(v8::Task* task);
54-
void CallDelayedOnForegroundThread(v8::Task* task, double delay_in_seconds);
53+
void CallOnForegroundThread(std::unique_ptr<v8::Task> task);
54+
void CallDelayedOnForegroundThread(std::unique_ptr<v8::Task> task,
55+
double delay_in_seconds);
5556

5657
void Shutdown();
5758

@@ -64,7 +65,7 @@ class PerIsolatePlatformData {
6465

6566
private:
6667
static void FlushTasks(uv_async_t* handle);
67-
static void RunForegroundTask(v8::Task* task);
68+
static void RunForegroundTask(std::unique_ptr<v8::Task> task);
6869
static void RunForegroundTask(uv_timer_t* timer);
6970

7071
int ref_count_ = 1;

0 commit comments

Comments
 (0)