From 3da36fe00e5d85414031ae812e473f16629d8645 Mon Sep 17 00:00:00 2001 From: Alexis Campailla Date: Thu, 16 Jan 2014 03:18:55 -0800 Subject: [PATCH] cluster: handle bind errors on Windows 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. --- lib/net.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/net.js b/lib/net.js index 0bcacec0afd..be5e6f69417 100644 --- a/lib/net.js +++ b/lib/net.js @@ -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) { @@ -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; }; @@ -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) { @@ -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'); @@ -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');