Skip to content

Commit

Permalink
Check if enough FDs are free, instead counting the total free FDs. (#…
Browse files Browse the repository at this point in the history
…1929)

Signed-off-by: Tomoya.Fujita <[email protected]>
  • Loading branch information
fujitatomoya authored and dirk-thomas committed May 21, 2020
1 parent df6872f commit 2ce4879
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 14 deletions.
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

0 comments on commit 2ce4879

Please sign in to comment.