|
|
@ -42,6 +42,7 @@ var getsockname = binding.getsockname; |
|
|
|
var errnoException = binding.errnoException; |
|
|
|
var EINPROGRESS = binding.EINPROGRESS; |
|
|
|
var ENOENT = binding.ENOENT; |
|
|
|
var EMFILE = binding.EMFILE; |
|
|
|
var END_OF_FILE = 42; |
|
|
|
|
|
|
|
|
|
|
@ -238,6 +239,29 @@ var ioWatchers = new FreeList("iowatcher", 100, function () { |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// waitingForFDs stores servers which have experienced EMFILE.
|
|
|
|
// When a file descriptor becomes available through closeFD()
|
|
|
|
// a server from waitingForFDs is started.
|
|
|
|
|
|
|
|
var waitingForFDs = []; |
|
|
|
|
|
|
|
function closeFD(fd) { |
|
|
|
close(fd); |
|
|
|
|
|
|
|
// Try to recover from EMFILE
|
|
|
|
|
|
|
|
var server, serverFD; |
|
|
|
while (server = waitingForFDs.shift()) { |
|
|
|
serverFD = parseInt(server.fd); |
|
|
|
if (serverFD && serverFD > 0) { |
|
|
|
server.watcher.set(serverFD, true, false); |
|
|
|
server.watcher.start(); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Allocated on demand.
|
|
|
|
var pool = null; |
|
|
|
function allocNewPool () { |
|
|
@ -675,7 +699,7 @@ Stream.prototype.destroy = function (exception) { |
|
|
|
|
|
|
|
// FIXME Bug when this.fd == 0
|
|
|
|
if (typeof this.fd == 'number') { |
|
|
|
close(this.fd); |
|
|
|
closeFD(this.fd); |
|
|
|
this.fd = null; |
|
|
|
process.nextTick(function () { |
|
|
|
if (exception) self.emit('error', exception); |
|
|
@ -733,7 +757,16 @@ function Server (listener) { |
|
|
|
self.watcher.host = self; |
|
|
|
self.watcher.callback = function () { |
|
|
|
while (self.fd) { |
|
|
|
var peerInfo = accept(self.fd); |
|
|
|
try { |
|
|
|
var peerInfo = accept(self.fd); |
|
|
|
} catch (e) { |
|
|
|
if (e.errno == EMFILE) { |
|
|
|
waitingForFDs.push(self); |
|
|
|
self.watcher.stop(); |
|
|
|
return; |
|
|
|
} |
|
|
|
throw e; |
|
|
|
} |
|
|
|
if (!peerInfo) return; |
|
|
|
|
|
|
|
var s = new Stream(peerInfo.fd); |
|
|
@ -846,7 +879,7 @@ Server.prototype.close = function () { |
|
|
|
|
|
|
|
self.watcher.stop(); |
|
|
|
|
|
|
|
close(self.fd); |
|
|
|
closeFD(self.fd); |
|
|
|
self.fd = null; |
|
|
|
|
|
|
|
if (self.type === "unix") { |
|
|
|