Browse Source

dgram: make .bind() always asynchronous

v0.9.1-release
Ben Noordhuis 13 years ago
parent
commit
332fea5ac1
  1. 70
      lib/dgram.js

70
lib/dgram.js

@ -43,11 +43,6 @@ function isIP(address) {
function lookup(address, family, callback) { function lookup(address, family, callback) {
// implicit 'bind before send' needs to run on the same tick
var matchedFamily = isIP(address);
if (matchedFamily)
return callback(null, address, matchedFamily);
if (!dns) if (!dns)
dns = require('dns'); dns = require('dns');
@ -111,31 +106,36 @@ exports.createSocket = function(type, listener) {
}; };
Socket.prototype.bind = function(port, address) { Socket.prototype.bind = function(port, address, callback) {
var self = this; var self = this;
self._healthCheck(); self._healthCheck();
if (typeof callback === 'function')
self.once('listening', callback);
// resolve address first // resolve address first
self._handle.lookup(address, function(err, ip) { self._handle.lookup(address, function(err, ip) {
if (!err) { if (!self._handle)
if (self._handle.bind(ip, port || 0, /*flags=*/0)) { return; // handle has been closed in the mean time
err = errnoException(errno, 'bind');
}
else {
self._bound = true;
self._startReceiving();
self.emit('listening');
}
}
if (err) { if (err) {
// caller may not have had a chance yet to register its self.emit('error', err);
// error event listener so defer the error to the next tick return;
process.nextTick(function() { }
self.emit('error', err);
}); if (self._handle.bind(ip, port || 0, /*flags=*/ 0)) {
self.emit('error', errnoException(errno, 'bind'));
return;
} }
self._handle.onmessage = onMessage;
self._handle.recvStart();
self._receiving = true;
self._bound = true;
self.fd = -42; // compatibility hack
self.emit('listening');
}); });
}; };
@ -174,7 +174,14 @@ Socket.prototype.send = function(buffer,
callback = callback || noop; callback = callback || noop;
self._healthCheck(); self._healthCheck();
self._startReceiving();
if (!self._bound) {
self.bind(0, null);
self.once('listening', function() {
self.send(buffer, offset, length, port, address, callback);
});
return;
}
self._handle.lookup(address, function(err, ip) { self._handle.lookup(address, function(err, ip) {
if (err) { if (err) {
@ -309,25 +316,6 @@ Socket.prototype._healthCheck = function() {
}; };
Socket.prototype._startReceiving = function() {
if (this._receiving)
return;
if (!this._bound) {
this.bind(); // bind to random port
// sanity check
if (!this._bound)
throw new Error('implicit bind failed');
}
this._handle.onmessage = onMessage;
this._handle.recvStart();
this._receiving = true;
this.fd = -42; // compatibility hack
};
Socket.prototype._stopReceiving = function() { Socket.prototype._stopReceiving = function() {
if (!this._receiving) if (!this._receiving)
return; return;

Loading…
Cancel
Save