Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if enough FDs are free, instead counting the total free FDs. #1929

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions utilities/xmlrpcpp/include/xmlrpcpp/XmlRpcServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ namespace XmlRpc {
//! Create a new connection object for processing requests from a specific client.
virtual XmlRpcServerConnection* createConnection(int socket);

//! Count number of free file descriptors
int countFreeFDs();
//! Check if enough number of free file descriptors
bool enoughFreeFDs();

// Whether the introspection API is supported by this server
bool _introspectionEnabled;
Expand Down
26 changes: 14 additions & 12 deletions utilities/xmlrpcpp/src/XmlRpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ XmlRpcServer::acceptConnection()
_accept_retry_time_sec = _disp.getTime() + ACCEPT_RETRY_INTERVAL_SEC;
return 0; // Stop monitoring this FD
}
else if( countFreeFDs() < FREE_FD_BUFFER )
else if ( !enoughFreeFDs() )
{
XmlRpcSocket::close(s);
XmlRpcUtil::error("XmlRpcServer::acceptConnection: Rejecting client, not enough free file descriptors");
Expand All @@ -216,12 +216,11 @@ XmlRpcServer::acceptConnection()
return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd
}

int XmlRpcServer::countFreeFDs() {
// NOTE(austin): this function is not free, but in a few small tests it only
// takes about 1.2mS when querying 50k file descriptors.
bool XmlRpcServer::enoughFreeFDs() {
// This function is just to check if enough FDs are there.
//
// If the underlying system calls here fail, this will print an error and
// return 0
// return false

#if !defined(_WINDOWS)
int free_fds = 0;
Expand All @@ -230,10 +229,9 @@ int XmlRpcServer::countFreeFDs() {

// Get the current soft limit on the number of file descriptors.
if(getrlimit(RLIMIT_NOFILE, &limit) == 0) {
// If we have infinite file descriptors, always return FREE_FD_BUFFER so
// that we never hit the low-water mark.
// If we have infinite file descriptors, always return true.
if( limit.rlim_max == RLIM_INFINITY ) {
return FREE_FD_BUFFER;
return true;
}

// Poll the available file descriptors.
Expand All @@ -245,25 +243,29 @@ int XmlRpcServer::countFreeFDs() {
if(pollfds[i].revents & POLLNVAL) {
free_fds++;
}
if (free_fds >= FREE_FD_BUFFER) {
// Checked enough FDs are not opened.
return true;
}
}
} else {
// poll() may fail if interrupted, if the pollfds array is a bad pointer,
// if nfds exceeds RLIMIT_NOFILE, or if the system is out of memory.
XmlRpcUtil::error("XmlRpcServer::countFreeFDs: poll() failed: %s",
XmlRpcUtil::error("XmlRpcServer::enoughFreeFDs: poll() failed: %s",
strerror(errno));
}
} else {
// The man page for getrlimit says that it can fail if the requested
// resource is invalid or the second argument is invalid. I'm not sure
// either of these can actually fail in this code, but it's better to
// check.
XmlRpcUtil::error("XmlRpcServer::countFreeFDs: Could not get open file "
XmlRpcUtil::error("XmlRpcServer::enoughFreeFDs: Could not get open file "
"limit, getrlimit() failed: %s", strerror(errno));
}

return free_fds;
return false;
#else
return FREE_FD_BUFFER;
return true;
#endif
}

Expand Down