THRIFT-2789 TNonblockingServer leaks socket FD's under load

Client: C++
Patch: Sergey <drigh@deviantart.com> and Qiao Mu <qiaomuf@gmail.com>
This commit is contained in:
Jens Geyer 2014-12-04 21:49:07 +01:00
parent 78c57e1720
commit fb05cf67db
2 changed files with 14 additions and 3 deletions

View File

@ -290,8 +290,10 @@ public:
if (task->state_ == ThreadManager::Task::EXECUTING) {
try {
task->run();
} catch (...) {
// XXX need to log this
} catch(const std::exception& e) {
GlobalOutput.printf("[ERROR] task->run() raised an exception: %s", e.what());
} catch(...) {
GlobalOutput.printf("[ERROR] task->run() raised an unknown exception");
}
}
}

View File

@ -283,6 +283,7 @@ public:
void forceClose() {
appState_ = APP_CLOSE_CONNECTION;
if (!notifyIOThread()) {
close();
throw TException("TConnection::forceClose: failed write on notify pipe");
}
}
@ -342,6 +343,8 @@ public:
// Signal completion back to the libevent thread via a pipe
if (!connection_->notifyIOThread()) {
GlobalOutput.printf("TNonblockingServer: failed to notifyIOThread, closing.");
connection_->close();
throw TException("TNonblockingServer::Task::run: failed write on notify pipe");
}
}
@ -568,6 +571,9 @@ void TNonblockingServer::TConnection::transition() {
// The ThreadManager is not ready to handle any more tasks (it's probably shutting down).
GlobalOutput.printf("IllegalStateException: Server::process() %s", ise.what());
close();
} catch (TimedOutException& to) {
GlobalOutput.printf("[ERROR] TimedOutException: Server::process() %s", to.what());
close();
}
// Set this connection idle so that libevent doesn't process more
@ -969,7 +975,10 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) {
if (clientConnection->getIOThreadNumber() == 0) {
clientConnection->transition();
} else {
clientConnection->notifyIOThread();
if (!clientConnection->notifyIOThread()) {
GlobalOutput.perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno);
returnConnection(clientConnection);
}
}
// addrLen is written by the accept() call, so needs to be set before the next call.