cares_wrap: don't set oncomplete property from c++
authorBen Noordhuis <info@bnoordhuis.nl>
Mon, 12 Aug 2013 15:54:11 +0000 (17:54 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Mon, 12 Aug 2013 17:08:03 +0000 (19:08 +0200)
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
src/cares_wrap.cc

index 8e6ed5c..dd27482 100644 (file)
@@ -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;
   }
index 746dc02..f3725d3 100644 (file)
@@ -236,15 +236,9 @@ class QueryWrap {
 
   virtual ~QueryWrap() {
     assert(!persistent().IsEmpty());
-    object()->Delete(oncomplete_sym);
     persistent().Dispose();
   }
 
-  void SetOnComplete(Handle<Value> 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<Value>& args) {
   assert(!args.IsConstructCall());
   assert(args[0]->IsObject());
   assert(args[1]->IsString());
-  assert(args[2]->IsFunction());
 
   Local<Object> req_wrap_obj = args[0].As<Object>();
   Local<String> string = args[1].As<String>();
-  Local<Function> callback = args[2].As<Function>();
-
   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<Value>& args) {
   Local<Function> callback = args[3].As<Function>();
 
   Wrap* wrap = new Wrap(req_wrap_obj);
-  wrap->SetOnComplete(callback);
 
   String::Utf8Value name(string);
   int err = wrap->Send(*name, family);