Servers shouldn't die on EMFILE
This commit is contained in:
parent
b36f11d7b5
commit
9331218449
39
lib/net.js
39
lib/net.js
@ -42,6 +42,7 @@ var getsockname = binding.getsockname;
|
|||||||
var errnoException = binding.errnoException;
|
var errnoException = binding.errnoException;
|
||||||
var EINPROGRESS = binding.EINPROGRESS;
|
var EINPROGRESS = binding.EINPROGRESS;
|
||||||
var ENOENT = binding.ENOENT;
|
var ENOENT = binding.ENOENT;
|
||||||
|
var EMFILE = binding.EMFILE;
|
||||||
var END_OF_FILE = 42;
|
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.
|
// Allocated on demand.
|
||||||
var pool = null;
|
var pool = null;
|
||||||
function allocNewPool () {
|
function allocNewPool () {
|
||||||
@ -675,7 +699,7 @@ Stream.prototype.destroy = function (exception) {
|
|||||||
|
|
||||||
// FIXME Bug when this.fd == 0
|
// FIXME Bug when this.fd == 0
|
||||||
if (typeof this.fd == 'number') {
|
if (typeof this.fd == 'number') {
|
||||||
close(this.fd);
|
closeFD(this.fd);
|
||||||
this.fd = null;
|
this.fd = null;
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
if (exception) self.emit('error', exception);
|
if (exception) self.emit('error', exception);
|
||||||
@ -733,7 +757,16 @@ function Server (listener) {
|
|||||||
self.watcher.host = self;
|
self.watcher.host = self;
|
||||||
self.watcher.callback = function () {
|
self.watcher.callback = function () {
|
||||||
while (self.fd) {
|
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;
|
if (!peerInfo) return;
|
||||||
|
|
||||||
var s = new Stream(peerInfo.fd);
|
var s = new Stream(peerInfo.fd);
|
||||||
@ -846,7 +879,7 @@ Server.prototype.close = function () {
|
|||||||
|
|
||||||
self.watcher.stop();
|
self.watcher.stop();
|
||||||
|
|
||||||
close(self.fd);
|
closeFD(self.fd);
|
||||||
self.fd = null;
|
self.fd = null;
|
||||||
|
|
||||||
if (self.type === "unix") {
|
if (self.type === "unix") {
|
||||||
|
@ -1294,6 +1294,7 @@ void InitNet2(Handle<Object> target) {
|
|||||||
NODE_SET_METHOD(target, "errnoException", CreateErrnoException);
|
NODE_SET_METHOD(target, "errnoException", CreateErrnoException);
|
||||||
|
|
||||||
target->Set(String::NewSymbol("ENOENT"), Integer::New(ENOENT));
|
target->Set(String::NewSymbol("ENOENT"), Integer::New(ENOENT));
|
||||||
|
target->Set(String::NewSymbol("EMFILE"), Integer::New(EMFILE));
|
||||||
target->Set(String::NewSymbol("EINPROGRESS"), Integer::New(EINPROGRESS));
|
target->Set(String::NewSymbol("EINPROGRESS"), Integer::New(EINPROGRESS));
|
||||||
target->Set(String::NewSymbol("EINTR"), Integer::New(EINTR));
|
target->Set(String::NewSymbol("EINTR"), Integer::New(EINTR));
|
||||||
target->Set(String::NewSymbol("EACCES"), Integer::New(EACCES));
|
target->Set(String::NewSymbol("EACCES"), Integer::New(EACCES));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user