From 6cd7fd7d243fcf36b047b9c22a79927fb714d6cd Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 12 Aug 2013 17:54:11 +0200 Subject: [PATCH] cares_wrap: don't set oncomplete property from c++ Don't set the oncomplete property in src/cares_wrap.cc, we can do it just as easily in lib/dns.js. Switch two closures to the 'function with _this_ object' model. Makes it impossible for an overzealous closure to capture too much context and accidentally hold on to too much memory. --- lib/dns.js | 64 ++++++++++++++++++++++++----------------------- src/cares_wrap.cc | 11 -------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/lib/dns.js b/lib/dns.js index 8e6ed5c061..dd274825b2 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -78,6 +78,18 @@ function makeAsync(callback) { } +function onlookup(err, addresses) { + if (err) { + return this.callback(errnoException(err, 'getaddrinfo')); + } + if (this.family) { + this.callback(null, addresses[0], this.family); + } else { + this.callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4); + } +} + + // Easy DNS A/AAAA look up // lookup(domain, [family,] callback) exports.lookup = function(domain, family, callback) { @@ -115,49 +127,39 @@ exports.lookup = function(domain, family, callback) { return {}; } - function onanswer(err, addresses) { - if (err) { - return callback(errnoException(err, 'getaddrinfo')); - } - if (family) { - callback(null, addresses[0], family); - } else { - callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4); - } - } - - var req = {}; + var req = { + callback: callback, + family: family, + oncomplete: onlookup + }; var err = cares.getaddrinfo(req, domain, family); - - if (err) { - throw errnoException(err, 'getaddrinfo'); - } - - req.oncomplete = onanswer; + if (err) throw errnoException(err, 'getaddrinfo'); callback.immediately = true; return req; }; +function onresolve(err, result) { + if (err) + this.callback(errnoException(err, this.bindingName)); + else + this.callback(null, result); +} + + function resolver(bindingName) { var binding = cares[bindingName]; return function query(name, callback) { - function onanswer(err, result) { - if (err) - callback(errnoException(err, bindingName)); - else - callback(null, result); - } - callback = makeAsync(callback); - var req = {}; - var err = binding(req, name, onanswer); - if (err) { - throw errnoException(err, bindingName); - } - + var req = { + bindingName: bindingName, + callback: callback, + oncomplete: onresolve + }; + var err = binding(req, name); + if (err) throw errnoException(err, bindingName); callback.immediately = true; return req; } diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 746dc02f25..f3725d39bd 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -236,15 +236,9 @@ class QueryWrap { virtual ~QueryWrap() { assert(!persistent().IsEmpty()); - object()->Delete(oncomplete_sym); persistent().Dispose(); } - void SetOnComplete(Handle oncomplete) { - assert(oncomplete->IsFunction()); - object()->Set(oncomplete_sym, oncomplete); - } - // Subclasses should implement the appropriate Send method. virtual int Send(const char* name) { assert(0); @@ -741,14 +735,10 @@ static void Query(const FunctionCallbackInfo& args) { assert(!args.IsConstructCall()); assert(args[0]->IsObject()); assert(args[1]->IsString()); - assert(args[2]->IsFunction()); Local req_wrap_obj = args[0].As(); Local string = args[1].As(); - Local callback = args[2].As(); - Wrap* wrap = new Wrap(req_wrap_obj); - wrap->SetOnComplete(callback); String::Utf8Value name(string); int err = wrap->Send(*name); @@ -774,7 +764,6 @@ static void QueryWithFamily(const FunctionCallbackInfo& args) { Local callback = args[3].As(); Wrap* wrap = new Wrap(req_wrap_obj); - wrap->SetOnComplete(callback); String::Utf8Value name(string); int err = wrap->Send(*name, family);