Skip to content
This repository
Browse code

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.
  • Loading branch information...
commit 3da36fe00e5d85414031ae812e473f16629d8645 1 parent e7a03f1
orangemocha authored tjfontaine committed

Showing 1 changed file with 23 additions and 4 deletions. Show diff stats Hide diff stats

  1. +23 4 lib/net.js
27 lib/net.js
@@ -999,6 +999,12 @@ exports.Server = Server;
999 999
1000 1000 function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
1001 1001
  1002 +function _listen(handle, backlog) {
  1003 + // Use a backlog of 512 entries. We pass 511 to the listen() call because
  1004 + // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
  1005 + // which will thus give us a backlog of 512 entries.
  1006 + return handle.listen(backlog || 511);
  1007 +}
1002 1008
1003 1009 var createServerHandle = exports._createServerHandle =
1004 1010 function(address, port, addressType, fd) {
@@ -1046,6 +1052,17 @@ var createServerHandle = exports._createServerHandle =
1046 1052 return err;
1047 1053 }
1048 1054
  1055 + if (process.platform === 'win32') {
  1056 + // On Windows, we always listen to the socket before sending it to
  1057 + // the worker (see uv_tcp_duplicate_socket). So we better do it here
  1058 + // so that we can handle any bind-time or listen-time errors early.
  1059 + err = _listen(handle);
  1060 + if (err) {
  1061 + handle.close();
  1062 + return err;
  1063 + }
  1064 + }
  1065 +
1049 1066 return handle;
1050 1067 };
1051 1068
@@ -1054,6 +1071,8 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
1054 1071 debug('listen2', address, port, addressType, backlog);
1055 1072 var self = this;
1056 1073
  1074 + var alreadyListening = false;
  1075 +
1057 1076 // If there is not yet a handle, we need to create one and bind.
1058 1077 // In the case of a server sent via IPC, we don't need to do this.
1059 1078 if (!self._handle) {
@@ -1066,6 +1085,7 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
1066 1085 });
1067 1086 return;
1068 1087 }
  1088 + alreadyListening = (process.platform === 'win32');
1069 1089 self._handle = rval;
1070 1090 } else {
1071 1091 debug('_listen2: have a handle already');
@@ -1074,10 +1094,9 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
1074 1094 self._handle.onconnection = onconnection;
1075 1095 self._handle.owner = self;
1076 1096
1077   - // Use a backlog of 512 entries. We pass 511 to the listen() call because
1078   - // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
1079   - // which will thus give us a backlog of 512 entries.
1080   - var err = self._handle.listen(backlog || 511);
  1097 + var err = 0;
  1098 + if (!alreadyListening)
  1099 + err = _listen(self._handle, backlog);
1081 1100
1082 1101 if (err) {
1083 1102 var ex = errnoException(err, 'listen');

0 comments on commit 3da36fe

Please sign in to comment.
Something went wrong with that request. Please try again.