Browse Source

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.
v0.11.6-release
Ben Noordhuis 12 years ago
parent
commit
6cd7fd7d24
  1. 64
      lib/dns.js
  2. 11
      src/cares_wrap.cc

64
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 resolver(bindingName) {
var binding = cares[bindingName];
return function query(name, callback) {
function onanswer(err, result) {
function onresolve(err, result) {
if (err)
callback(errnoException(err, bindingName));
this.callback(errnoException(err, this.bindingName));
else
callback(null, result);
this.callback(null, result);
}
callback = makeAsync(callback);
var req = {};
var err = binding(req, name, onanswer);
if (err) {
throw errnoException(err, bindingName);
}
function resolver(bindingName) {
var binding = cares[bindingName];
return function query(name, callback) {
callback = makeAsync(callback);
var req = {
bindingName: bindingName,
callback: callback,
oncomplete: onresolve
};
var err = binding(req, name);
if (err) throw errnoException(err, bindingName);
callback.immediately = true;
return req;
}

11
src/cares_wrap.cc

@ -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);

Loading…
Cancel
Save