Skip to content
Closed
Prev Previous commit
Next Next commit
fixup! src: fix cleanup hook removal for InspectorTimer
  • Loading branch information
addaleax committed Mar 27, 2020
commit d9689dbda366da38f96e7f345364e06b998abbad
31 changes: 20 additions & 11 deletions src/inspector_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -340,31 +340,26 @@ class InspectorTimer {
int64_t interval_ms = 1000 * interval_s;
uv_timer_start(&timer_, OnTimer, interval_ms, interval_ms);
timer_.data = this;

env->AddCleanupHook(CleanupHook, this);
}

InspectorTimer(const InspectorTimer&) = delete;

void Stop() {
if (timer_.data == nullptr) return;

env_->RemoveCleanupHook(CleanupHook, this);
timer_.data = nullptr;
uv_timer_stop(&timer_);
env_->CloseHandle(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
}

inline Environment* env() const { return env_; }

private:
static void OnTimer(uv_timer_t* uvtimer) {
InspectorTimer* timer = node::ContainerOf(&InspectorTimer::timer_, uvtimer);
timer->callback_(timer->data_);
}

static void CleanupHook(void* data) {
static_cast<InspectorTimer*>(data)->Stop();
}

static void TimerClosedCb(uv_handle_t* uvtimer) {
std::unique_ptr<InspectorTimer> timer(
node::ContainerOf(&InspectorTimer::timer_,
Expand All @@ -387,16 +382,29 @@ class InspectorTimerHandle {
InspectorTimerHandle(Environment* env, double interval_s,
V8InspectorClient::TimerCallback callback, void* data) {
timer_ = new InspectorTimer(env, interval_s, callback, data);

env->AddCleanupHook(CleanupHook, this);
}

InspectorTimerHandle(const InspectorTimerHandle&) = delete;

~InspectorTimerHandle() {
CHECK_NOT_NULL(timer_);
timer_->Stop();
timer_ = nullptr;
Stop();
}

private:
void Stop() {
if (timer_ != nullptr) {
timer_->env()->RemoveCleanupHook(CleanupHook, this);
timer_->Stop();
}
timer_ = nullptr;
}

static void CleanupHook(void* data) {
static_cast<InspectorTimerHandle*>(data)->Stop();
}

InspectorTimer* timer_;
};

Expand Down Expand Up @@ -717,8 +725,9 @@ class NodeInspectorClient : public V8InspectorClient {
bool is_main_;
bool running_nested_loop_ = false;
std::unique_ptr<V8Inspector> client_;
std::unordered_map<int, std::unique_ptr<ChannelImpl>> channels_;
// Note: ~ChannelImpl may access timers_ so timers_ has to come first.
std::unordered_map<void*, InspectorTimerHandle> timers_;
std::unordered_map<int, std::unique_ptr<ChannelImpl>> channels_;
int next_session_id_ = 1;
bool waiting_for_resume_ = false;
bool waiting_for_frontend_ = false;
Expand Down