@@ -136,8 +136,9 @@ class ChannelWrap : public AsyncWrap {
136
136
137
137
void Setup ();
138
138
void EnsureServers ();
139
+ void CleanupTimer ();
139
140
140
- inline uv_timer_t * timer_handle () { return & timer_handle_; }
141
+ inline uv_timer_t * timer_handle () { return timer_handle_; }
141
142
inline ares_channel cares_channel () { return channel_; }
142
143
inline bool query_last_ok () const { return query_last_ok_; }
143
144
inline void set_query_last_ok (bool ok) { query_last_ok_ = ok; }
@@ -152,7 +153,7 @@ class ChannelWrap : public AsyncWrap {
152
153
static void AresTimeout (uv_timer_t * handle);
153
154
154
155
private:
155
- uv_timer_t timer_handle_;
156
+ uv_timer_t * timer_handle_;
156
157
ares_channel channel_;
157
158
bool query_last_ok_;
158
159
bool is_servers_default_;
@@ -163,6 +164,7 @@ class ChannelWrap : public AsyncWrap {
163
164
ChannelWrap::ChannelWrap (Environment* env,
164
165
Local<Object> object)
165
166
: AsyncWrap(env, object, PROVIDER_DNSCHANNEL),
167
+ timer_handle_ (nullptr ),
166
168
channel_(nullptr ),
167
169
query_last_ok_(true ),
168
170
is_servers_default_(true ),
@@ -236,7 +238,8 @@ RB_GENERATE_STATIC(node_ares_task_list, node_ares_task, node, cmp_ares_tasks)
236
238
/* This is called once per second by loop->timer. It is used to constantly */
237
239
/* call back into c-ares for possibly processing timeouts. */
238
240
void ChannelWrap::AresTimeout (uv_timer_t * handle) {
239
- ChannelWrap* channel = ContainerOf (&ChannelWrap::timer_handle_, handle);
241
+ ChannelWrap* channel = static_cast <ChannelWrap*>(handle->data );
242
+ CHECK_EQ (channel->timer_handle (), handle);
240
243
CHECK_EQ (false , RB_EMPTY (channel->task_list ()));
241
244
ares_process_fd (channel->cares_channel (), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
242
245
}
@@ -505,25 +508,29 @@ void ChannelWrap::Setup() {
505
508
506
509
/* Initialize the timeout timer. The timer won't be started until the */
507
510
/* first socket is opened. */
508
- uv_timer_init (env ()->event_loop (), &timer_handle_);
509
- env ()->RegisterHandleCleanup (
510
- reinterpret_cast <uv_handle_t *>(&timer_handle_),
511
- [](Environment* env, uv_handle_t * handle, void * arg) {
512
- uv_close (handle, [](uv_handle_t * handle) {
513
- ChannelWrap* channel = ContainerOf (
514
- &ChannelWrap::timer_handle_,
515
- reinterpret_cast <uv_timer_t *>(handle));
516
- channel->env ()->FinishHandleCleanup (handle);
517
- });
518
- },
519
- nullptr );
511
+ CleanupTimer ();
512
+ timer_handle_ = new uv_timer_t ();
513
+ timer_handle_->data = static_cast <void *>(this );
514
+ uv_timer_init (env ()->event_loop (), timer_handle_);
520
515
}
521
516
522
517
523
518
ChannelWrap::~ChannelWrap () {
524
519
if (library_inited_)
525
520
ares_library_cleanup ();
521
+
526
522
ares_destroy (channel_);
523
+ CleanupTimer ();
524
+ }
525
+
526
+ void ChannelWrap::CleanupTimer () {
527
+ if (!timer_handle_) return ;
528
+
529
+ uv_close (reinterpret_cast <uv_handle_t *>(timer_handle_),
530
+ [](uv_handle_t * handle) {
531
+ delete reinterpret_cast <uv_timer_t *>(handle);
532
+ });
533
+ timer_handle_ = nullptr ;
527
534
}
528
535
529
536
0 commit comments