summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2013-12-31 03:08:54 -0800
committerTrevor Norris <trev.norris@gmail.com>2014-01-04 03:04:13 -0800
commit9ff83c32e64a021421a96772ae96057b81a5f084 (patch)
treea8c4422a3854d8c56c177a72454f14bcc9d8f601
parenta40b46367406deb0e3c67dff8c5d609d1334519b (diff)
downloadnode-9ff83c32e64a021421a96772ae96057b81a5f084.tar.gz
net: run close callbacks in correct eloop phase
Instead of running the close callbacks seemingly synchronously instead of when the handle has actually been closed by libuv, instead run the callbacks in the uv__run_closing_handles() phase of the eloop.
-rw-r--r--lib/net.js85
1 files changed, 42 insertions, 43 deletions
diff --git a/lib/net.js b/lib/net.js
index afb2d0dec..b49cd8c19 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -1078,11 +1078,10 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
if (err) {
var ex = errnoException(err, 'listen');
- self._handle.close();
- self._handle = null;
- process.nextTick(function() {
+ self._handle.close(function() {
self.emit('error', ex);
});
+ self._handle = null;
return;
}
@@ -1276,58 +1275,58 @@ Server.prototype.getConnections = function(cb) {
};
-Server.prototype.close = function(cb) {
- function onSlaveClose() {
- if (--left !== 0) return;
+function emitWhenClosed(self) {
+ debug('SERVER: emitWhenClosed');
- self._connections = 0;
- self._emitCloseIfDrained();
+ if (self._handle || self._connections) {
+ debug('SERVER handle? %j connections? %d',
+ !!self._handle, self._connections);
+ return;
}
- if (!this._handle) {
- // Throw error. Follows net_legacy behaviour.
- throw new Error('Not running');
- }
+ debug('SERVER: emit close');
+ self.emit('close');
+}
- if (cb) {
- this.once('close', cb);
- }
- this._handle.close();
- this._handle = null;
- if (this._usingSlaves) {
- var self = this,
- left = this._slaves.length;
+function closeWhenDrained() {
+ var self = this.owner;
- // Increment connections to be sure that, even if all sockets will be closed
- // during polling of slaves, `close` event will be emitted only once.
- this._connections++;
+ // If no slaves then not much more to do.
+ if (!self._usingSlaves)
+ return emitWhenClosed(self);
- // Poll slaves
- this._slaves.forEach(function(slave) {
- slave.close(onSlaveClose);
+ var left = self._slaves.length;
+
+ // Increment connections to be sure that, even if all sockets will be closed
+ // during polling of slaves, `close` event will be emitted only once.
+ self.connections++;
+
+ // Poll slaves
+ self._slaves.forEach(function(slave) {
+ slave.close(function callOnSlaveClose() {
+ if (--left > 0)
+ return;
+
+ self._connections = 0;
+ emitWhenClosed(self);
});
- } else {
- this._emitCloseIfDrained();
- }
+ });
+}
- return this;
-};
-Server.prototype._emitCloseIfDrained = function() {
- debug('SERVER _emitCloseIfDrained');
- var self = this;
+Server.prototype.close = function(cb) {
+ // Throw error. Follows net_legacy behaviour.
+ if (!this._handle)
+ throw new Error('Not running');
- if (self._handle || self._connections) {
- debug('SERVER handle? %j connections? %d',
- !!self._handle, self._connections);
- return;
- }
+ if (cb)
+ this.once('close', cb);
- process.nextTick(function() {
- debug('SERVER: emit close');
- self.emit('close');
- });
+ this._handle.close(closeWhenDrained);
+ this._handle = null;
+
+ return this;
};