Skip to content

Commit

Permalink
cluster: handle bind errors on Windows
Browse files Browse the repository at this point in the history
Before sending a socket from a cluster master to a worker,
we would call listen in UV but not handle the error.

I made createServerHandle call listen on Windows so we get a chance
the handle any bind/listen errors early.

This fix is 100% windows specific.
It fixes test-cluster-bind-twice and
test-cluster-shared-handle-bind-error on Windows.
  • Loading branch information
orangemocha authored and tjfontaine committed Feb 14, 2014
1 parent e7a03f1 commit 3da36fe
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,12 @@ exports.Server = Server;

function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }

function _listen(handle, backlog) {
// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
return handle.listen(backlog || 511);
}

var createServerHandle = exports._createServerHandle =
function(address, port, addressType, fd) {
Expand Down Expand Up @@ -1046,6 +1052,17 @@ var createServerHandle = exports._createServerHandle =
return err;
}

if (process.platform === 'win32') {
// On Windows, we always listen to the socket before sending it to
// the worker (see uv_tcp_duplicate_socket). So we better do it here
// so that we can handle any bind-time or listen-time errors early.
err = _listen(handle);
if (err) {
handle.close();
return err;
}
}

return handle;
};

Expand All @@ -1054,6 +1071,8 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
debug('listen2', address, port, addressType, backlog);
var self = this;

var alreadyListening = false;

// If there is not yet a handle, we need to create one and bind.
// In the case of a server sent via IPC, we don't need to do this.
if (!self._handle) {
Expand All @@ -1066,6 +1085,7 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
});
return;
}
alreadyListening = (process.platform === 'win32');
self._handle = rval;
} else {
debug('_listen2: have a handle already');
Expand All @@ -1074,10 +1094,9 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
self._handle.onconnection = onconnection;
self._handle.owner = self;

// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
var err = self._handle.listen(backlog || 511);
var err = 0;
if (!alreadyListening)
err = _listen(self._handle, backlog);

if (err) {
var ex = errnoException(err, 'listen');
Expand Down

0 comments on commit 3da36fe

Please sign in to comment.