Skip to content

Commit 332fea5

Browse files
committed
dgram: make .bind() always asynchronous
1 parent 59b584c commit 332fea5

File tree

1 file changed

+29
-41
lines changed

1 file changed

+29
-41
lines changed

lib/dgram.js

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ function isIP(address) {
4343

4444

4545
function lookup(address, family, callback) {
46-
// implicit 'bind before send' needs to run on the same tick
47-
var matchedFamily = isIP(address);
48-
if (matchedFamily)
49-
return callback(null, address, matchedFamily);
50-
5146
if (!dns)
5247
dns = require('dns');
5348

@@ -111,31 +106,36 @@ exports.createSocket = function(type, listener) {
111106
};
112107

113108

114-
Socket.prototype.bind = function(port, address) {
109+
Socket.prototype.bind = function(port, address, callback) {
115110
var self = this;
116111

117112
self._healthCheck();
118113

114+
if (typeof callback === 'function')
115+
self.once('listening', callback);
116+
119117
// resolve address first
120118
self._handle.lookup(address, function(err, ip) {
121-
if (!err) {
122-
if (self._handle.bind(ip, port || 0, /*flags=*/0)) {
123-
err = errnoException(errno, 'bind');
124-
}
125-
else {
126-
self._bound = true;
127-
self._startReceiving();
128-
self.emit('listening');
129-
}
130-
}
119+
if (!self._handle)
120+
return; // handle has been closed in the mean time
131121

132122
if (err) {
133-
// caller may not have had a chance yet to register its
134-
// error event listener so defer the error to the next tick
135-
process.nextTick(function() {
136-
self.emit('error', err);
137-
});
123+
self.emit('error', err);
124+
return;
125+
}
126+
127+
if (self._handle.bind(ip, port || 0, /*flags=*/ 0)) {
128+
self.emit('error', errnoException(errno, 'bind'));
129+
return;
138130
}
131+
132+
self._handle.onmessage = onMessage;
133+
self._handle.recvStart();
134+
self._receiving = true;
135+
self._bound = true;
136+
self.fd = -42; // compatibility hack
137+
138+
self.emit('listening');
139139
});
140140
};
141141

@@ -174,7 +174,14 @@ Socket.prototype.send = function(buffer,
174174
callback = callback || noop;
175175

176176
self._healthCheck();
177-
self._startReceiving();
177+
178+
if (!self._bound) {
179+
self.bind(0, null);
180+
self.once('listening', function() {
181+
self.send(buffer, offset, length, port, address, callback);
182+
});
183+
return;
184+
}
178185

179186
self._handle.lookup(address, function(err, ip) {
180187
if (err) {
@@ -309,25 +316,6 @@ Socket.prototype._healthCheck = function() {
309316
};
310317

311318

312-
Socket.prototype._startReceiving = function() {
313-
if (this._receiving)
314-
return;
315-
316-
if (!this._bound) {
317-
this.bind(); // bind to random port
318-
319-
// sanity check
320-
if (!this._bound)
321-
throw new Error('implicit bind failed');
322-
}
323-
324-
this._handle.onmessage = onMessage;
325-
this._handle.recvStart();
326-
this._receiving = true;
327-
this.fd = -42; // compatibility hack
328-
};
329-
330-
331319
Socket.prototype._stopReceiving = function() {
332320
if (!this._receiving)
333321
return;

0 commit comments

Comments
 (0)