|
@ -922,36 +922,38 @@ function Server (/* [ options, ] listener */) { |
|
|
|
|
|
|
|
|
self.connections = 0; |
|
|
self.connections = 0; |
|
|
|
|
|
|
|
|
self.paused = false; |
|
|
|
|
|
self.pauseTimeout = 1000; |
|
|
|
|
|
|
|
|
|
|
|
self.allowHalfOpen = options.allowHalfOpen || false; |
|
|
self.allowHalfOpen = options.allowHalfOpen || false; |
|
|
|
|
|
|
|
|
function pause () { |
|
|
|
|
|
// We've hit the maximum file limit. What to do?
|
|
|
|
|
|
// Let's try again in 1 second.
|
|
|
|
|
|
self.watcher.stop(); |
|
|
|
|
|
|
|
|
|
|
|
// If we're already paused, don't do another timeout.
|
|
|
|
|
|
if (self.paused) return; |
|
|
|
|
|
|
|
|
|
|
|
setTimeout(function () { |
|
|
|
|
|
self.paused = false; |
|
|
|
|
|
// Make sure we haven't closed in the interim
|
|
|
|
|
|
if (typeof self.fd != 'number') return; |
|
|
|
|
|
self.watcher.start(); |
|
|
|
|
|
}, self.pauseTimeout); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.watcher = new IOWatcher(); |
|
|
self.watcher = new IOWatcher(); |
|
|
self.watcher.host = self; |
|
|
self.watcher.host = self; |
|
|
self.watcher.callback = function () { |
|
|
self.watcher.callback = function () { |
|
|
|
|
|
// Just in case we don't have a dummy fd.
|
|
|
|
|
|
if (!self._dummyFD) self._getDummyFD(); |
|
|
|
|
|
|
|
|
while (self.fd) { |
|
|
while (self.fd) { |
|
|
try { |
|
|
try { |
|
|
var peerInfo = accept(self.fd); |
|
|
var peerInfo = accept(self.fd); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
if (e.errno == EMFILE) { |
|
|
if (e.errno == EMFILE) { |
|
|
pause(); |
|
|
// Output a warning, but only at most every 5 seconds.
|
|
|
|
|
|
var now = new Date(); |
|
|
|
|
|
if (now - self._lastEMFILEWarning > 5000) { |
|
|
|
|
|
console.error("(node) Hit max file limit. Increase 'ulimit -n'."); |
|
|
|
|
|
} |
|
|
|
|
|
self._lastEMFILEWarning = now; |
|
|
|
|
|
|
|
|
|
|
|
// Gracefully reject pending clients by freeing up a file
|
|
|
|
|
|
// descriptor.
|
|
|
|
|
|
if (self._dummyFD) { |
|
|
|
|
|
close(self._dummyFD); |
|
|
|
|
|
self._dummyFD = null; |
|
|
|
|
|
while (true) { |
|
|
|
|
|
peerInfo = accept(self.fd); |
|
|
|
|
|
if (!peerInfo) break; |
|
|
|
|
|
close(peerInfo.fd); |
|
|
|
|
|
} |
|
|
|
|
|
self._getDummyFD(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
throw e; |
|
|
throw e; |
|
@ -1076,9 +1078,23 @@ Server.prototype._startWatcher = function () { |
|
|
this.emit("listening"); |
|
|
this.emit("listening"); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Server.prototype._getDummyFD = function () { |
|
|
|
|
|
try { |
|
|
|
|
|
this._dummyFD = socket("tcp"); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
this._dummyFD = null; |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Server.prototype._doListen = function () { |
|
|
Server.prototype._doListen = function () { |
|
|
var self = this; |
|
|
var self = this; |
|
|
|
|
|
|
|
|
|
|
|
// Grab a dummy fd for EMFILE conditions.
|
|
|
|
|
|
self._getDummyFD(); |
|
|
|
|
|
self._lastEMFILEWarning = 0; |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
bind(self.fd, arguments[0], arguments[1]); |
|
|
bind(self.fd, arguments[0], arguments[1]); |
|
|
} catch (err) { |
|
|
} catch (err) { |
|
@ -1120,6 +1136,11 @@ Server.prototype.close = function () { |
|
|
close(self.fd); |
|
|
close(self.fd); |
|
|
self.fd = null; |
|
|
self.fd = null; |
|
|
|
|
|
|
|
|
|
|
|
if (this._dummyFD) { |
|
|
|
|
|
close(this._dummyFD); |
|
|
|
|
|
this._dummyFD = null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (self.type === "unix") { |
|
|
if (self.type === "unix") { |
|
|
fs.unlink(self.path, function () { |
|
|
fs.unlink(self.path, function () { |
|
|
self.emit("close"); |
|
|
self.emit("close"); |
|
|