Skip to content

Commit 0c4353a

Browse files
addaleaxrvagg
authored andcommitted
inspector: make sure timer handles are cleaned up
It is not obvious that timer handles are cleaned up properly when the current `Environment` exits, nor that the `Environment` knows to keep track of the closing handles. This change may not be necessary, because timer handles close without non-trivial delay (i.e. at the end of the current event loop term), and JS-based inspector sessions (which are the only ones we can easily test) are destroyed when cleaning up, closing the timers as a result. I don’t know what happens for other kinds of inspector sessions, though. PR-URL: #26088 Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
1 parent 2ff1644 commit 0c4353a

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/inspector_agent.cc

+21-8
Original file line numberDiff line numberDiff line change
@@ -301,22 +301,30 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
301301

302302
class InspectorTimer {
303303
public:
304-
InspectorTimer(uv_loop_t* loop,
304+
InspectorTimer(Environment* env,
305305
double interval_s,
306306
V8InspectorClient::TimerCallback callback,
307-
void* data) : timer_(),
307+
void* data) : env_(env),
308308
callback_(callback),
309309
data_(data) {
310-
uv_timer_init(loop, &timer_);
310+
uv_timer_init(env->event_loop(), &timer_);
311311
int64_t interval_ms = 1000 * interval_s;
312312
uv_timer_start(&timer_, OnTimer, interval_ms, interval_ms);
313+
timer_.data = this;
314+
315+
env->AddCleanupHook(CleanupHook, this);
313316
}
314317

315318
InspectorTimer(const InspectorTimer&) = delete;
316319

317320
void Stop() {
318-
uv_timer_stop(&timer_);
319-
uv_close(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
321+
env_->RemoveCleanupHook(CleanupHook, this);
322+
323+
if (timer_.data == this) {
324+
timer_.data = nullptr;
325+
uv_timer_stop(&timer_);
326+
env_->CloseHandle(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
327+
}
320328
}
321329

322330
private:
@@ -325,6 +333,10 @@ class InspectorTimer {
325333
timer->callback_(timer->data_);
326334
}
327335

336+
static void CleanupHook(void* data) {
337+
static_cast<InspectorTimer*>(data)->Stop();
338+
}
339+
328340
static void TimerClosedCb(uv_handle_t* uvtimer) {
329341
std::unique_ptr<InspectorTimer> timer(
330342
node::ContainerOf(&InspectorTimer::timer_,
@@ -334,6 +346,7 @@ class InspectorTimer {
334346

335347
~InspectorTimer() {}
336348

349+
Environment* env_;
337350
uv_timer_t timer_;
338351
V8InspectorClient::TimerCallback callback_;
339352
void* data_;
@@ -343,9 +356,9 @@ class InspectorTimer {
343356

344357
class InspectorTimerHandle {
345358
public:
346-
InspectorTimerHandle(uv_loop_t* loop, double interval_s,
359+
InspectorTimerHandle(Environment* env, double interval_s,
347360
V8InspectorClient::TimerCallback callback, void* data) {
348-
timer_ = new InspectorTimer(loop, interval_s, callback, data);
361+
timer_ = new InspectorTimer(env, interval_s, callback, data);
349362
}
350363

351364
InspectorTimerHandle(const InspectorTimerHandle&) = delete;
@@ -540,7 +553,7 @@ class NodeInspectorClient : public V8InspectorClient {
540553
TimerCallback callback,
541554
void* data) override {
542555
timers_.emplace(std::piecewise_construct, std::make_tuple(data),
543-
std::make_tuple(env_->event_loop(), interval_s, callback,
556+
std::make_tuple(env_, interval_s, callback,
544557
data));
545558
}
546559

0 commit comments

Comments
 (0)