diff --git a/lib/cpp/src/server/TNonblockingServer.cpp b/lib/cpp/src/server/TNonblockingServer.cpp index 26e97c967..eb071a903 100644 --- a/lib/cpp/src/server/TNonblockingServer.cpp +++ b/lib/cpp/src/server/TNonblockingServer.cpp @@ -570,12 +570,12 @@ void TNonblockingServer::handleEvent(int fd, short which) { nTotalConnectionsDropped_++; if (overloadAction_ == T_OVERLOAD_CLOSE_ON_ACCEPT) { close(clientSocket); - continue; + return; } else if (overloadAction_ == T_OVERLOAD_DRAIN_TASK_QUEUE) { if (!drainPendingTask()) { // Nothing left to discard, so we drop connection instead. close(clientSocket); - continue; + return; } } } @@ -718,6 +718,13 @@ void TNonblockingServer::createNotificationPipe() { GlobalOutput.perror("TNonblockingServer::createNotificationPipe ", errno); throw TException("can't create notification pipe"); } + int flags; + if ((flags = fcntl(notificationPipeFDs_[0], F_GETFL, 0)) < 0 || + fcntl(notificationPipeFDs_[0], F_SETFL, flags | O_NONBLOCK) < 0) { + close(notificationPipeFDs_[0]); + close(notificationPipeFDs_[1]); + throw TException("TNonblockingServer::createNotificationPipe() O_NONBLOCK"); + } } /** diff --git a/lib/cpp/src/server/TNonblockingServer.h b/lib/cpp/src/server/TNonblockingServer.h index 2650dd119..b54764966 100644 --- a/lib/cpp/src/server/TNonblockingServer.h +++ b/lib/cpp/src/server/TNonblockingServer.h @@ -722,13 +722,17 @@ class TConnection { */ static void taskHandler(int fd, short /* which */, void* /* v */) { TConnection* connection; - if (read(fd, (void*)&connection, sizeof(TConnection*)) - != sizeof(TConnection*)) { - GlobalOutput.perror("TConnection::taskHandler read failed, resource leak", errno); - return; + ssize_t nBytes; + while ((nBytes = read(fd, (void*)&connection, sizeof(TConnection*))) + == sizeof(TConnection*)) { + connection->transition(); + } + if (nBytes > 0) { + throw TException("TConnection::taskHandler unexpected partial read"); + } + if (errno != EWOULDBLOCK && errno != EAGAIN) { + GlobalOutput.perror("TConnection::taskHandler read failed, resource leak", errno); } - - connection->transition(); } /**