-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: manage handles more explicitly in cares_wrap, node_stat_watcher #21093
Changes from all commits
0bf2b28
c62b30a
2897c15
95fc191
1156ee2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,7 +151,8 @@ class ChannelWrap : public AsyncWrap { | |
|
||
void Setup(); | ||
void EnsureServers(); | ||
void CleanupTimer(); | ||
void StartTimer(); | ||
void CloseTimer(); | ||
|
||
void ModifyActivityQueryCount(int count); | ||
|
||
|
@@ -313,13 +314,7 @@ void ares_sockstate_cb(void* data, | |
if (read || write) { | ||
if (!task) { | ||
/* New socket */ | ||
|
||
/* If this is the first socket then start the timer. */ | ||
uv_timer_t* timer_handle = channel->timer_handle(); | ||
if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) { | ||
CHECK(channel->task_list()->empty()); | ||
uv_timer_start(timer_handle, ChannelWrap::AresTimeout, 1000, 1000); | ||
} | ||
channel->StartTimer(); | ||
|
||
task = ares_task_create(channel, sock); | ||
if (task == nullptr) { | ||
|
@@ -349,7 +344,7 @@ void ares_sockstate_cb(void* data, | |
channel->env()->CloseHandle(&task->poll_watcher, ares_poll_close_cb); | ||
|
||
if (channel->task_list()->empty()) { | ||
uv_timer_stop(channel->timer_handle()); | ||
channel->CloseTimer(); | ||
} | ||
} | ||
} | ||
|
@@ -490,15 +485,26 @@ void ChannelWrap::Setup() { | |
} | ||
|
||
library_inited_ = true; | ||
} | ||
|
||
/* Initialize the timeout timer. The timer won't be started until the */ | ||
/* first socket is opened. */ | ||
CleanupTimer(); | ||
timer_handle_ = new uv_timer_t(); | ||
timer_handle_->data = static_cast<void*>(this); | ||
uv_timer_init(env()->event_loop(), timer_handle_); | ||
void ChannelWrap::StartTimer() { | ||
if (timer_handle_ == nullptr) { | ||
timer_handle_ = new uv_timer_t(); | ||
timer_handle_->data = static_cast<void*>(this); | ||
uv_timer_init(env()->event_loop(), timer_handle_); | ||
} else if (uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle_))) { | ||
return; | ||
} | ||
uv_timer_start(timer_handle_, AresTimeout, 1000, 1000); | ||
} | ||
|
||
void ChannelWrap::CloseTimer() { | ||
if (timer_handle_ == nullptr) | ||
return; | ||
|
||
env()->CloseHandle(timer_handle_, [](uv_timer_t* handle) { delete handle; }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tbh, I don’t quite understand why this side-steps the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In like 99.99% of cases, no. This is for the absolute edge cases where there's an error and we live through it. In most cases it'll get cleared via |
||
timer_handle_ = nullptr; | ||
} | ||
|
||
ChannelWrap::~ChannelWrap() { | ||
if (library_inited_) { | ||
|
@@ -508,17 +514,10 @@ ChannelWrap::~ChannelWrap() { | |
} | ||
|
||
ares_destroy(channel_); | ||
CleanupTimer(); | ||
CloseTimer(); | ||
} | ||
|
||
|
||
void ChannelWrap::CleanupTimer() { | ||
if (timer_handle_ == nullptr) return; | ||
|
||
env()->CloseHandle(timer_handle_, [](uv_timer_t* handle) { delete handle; }); | ||
timer_handle_ = nullptr; | ||
} | ||
|
||
void ChannelWrap::ModifyActivityQueryCount(int count) { | ||
active_query_count_ += count; | ||
if (active_query_count_ < 0) active_query_count_ = 0; | ||
|
@@ -566,6 +565,7 @@ void ChannelWrap::EnsureServers() { | |
/* destroy channel and reset channel */ | ||
ares_destroy(channel_); | ||
|
||
CloseTimer(); | ||
Setup(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,19 +77,15 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) { | |
|
||
StatWatcher::StatWatcher(Environment* env, Local<Object> wrap, bool use_bigint) | ||
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_STATWATCHER), | ||
watcher_(new uv_fs_poll_t), | ||
watcher_(nullptr), | ||
use_bigint_(use_bigint) { | ||
MakeWeak(); | ||
uv_fs_poll_init(env->event_loop(), watcher_); | ||
watcher_->data = static_cast<void*>(this); | ||
} | ||
|
||
|
||
StatWatcher::~StatWatcher() { | ||
if (IsActive()) { | ||
if (IsActive()) | ||
Stop(); | ||
} | ||
env()->CloseHandle(watcher_, [](uv_fs_poll_t* handle) { delete handle; }); | ||
} | ||
|
||
|
||
|
@@ -123,7 +119,7 @@ void StatWatcher::New(const FunctionCallbackInfo<Value>& args) { | |
} | ||
|
||
bool StatWatcher::IsActive() { | ||
return uv_is_active(reinterpret_cast<uv_handle_t*>(watcher_)) != 0; | ||
return watcher_ != nullptr; | ||
} | ||
|
||
void StatWatcher::IsActive(const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
|
@@ -156,6 +152,9 @@ void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) { | |
CHECK(args[2]->IsUint32()); | ||
const uint32_t interval = args[2].As<Uint32>()->Value(); | ||
|
||
wrap->watcher_ = new uv_fs_poll_t(); | ||
CHECK_EQ(0, uv_fs_poll_init(wrap->env()->event_loop(), wrap->watcher_)); | ||
wrap->watcher_->data = static_cast<void*>(wrap); | ||
// Safe, uv_ref/uv_unref are idempotent. | ||
if (persistent) | ||
uv_ref(reinterpret_cast<uv_handle_t*>(wrap->watcher_)); | ||
|
@@ -187,7 +186,8 @@ void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) { | |
|
||
|
||
void StatWatcher::Stop() { | ||
uv_fs_poll_stop(watcher_); | ||
env()->CloseHandle(watcher_, [](uv_fs_poll_t* handle) { delete handle; }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. um, wait, is it enough to replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
watcher_ = nullptr; | ||
MakeWeak(); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (timer_handle_ != nullptr) return;
- saves a level of indent.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit more complex if you look below. We also check if the handle is active in an
else if
. (We need to be able to calluv_timer_start
to restart the timer if it expired but the handle still exists.)