summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2012-04-07 19:19:06 +0200
committerMartin Sustrik <sustrik@250bpm.com>2012-04-08 06:36:17 +0200
commit123c0f5387ecef287dd11f4dc790fb76ee1c0f67 (patch)
tree3240cb260e6c9407065ad9e02d380c006b19eba1
parent3e20706643c7709483fcd7d436e89090171fcc0f (diff)
Handle insufficient resources on accept() decently
If accept() call fails due to insuffient OS resources the new connection is rejected. Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
-rw-r--r--src/ipc_listener.cpp5
-rw-r--r--src/tcp_listener.cpp9
2 files changed, 11 insertions, 3 deletions
diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp
index b3e5693..743ca86 100644
--- a/src/ipc_listener.cpp
+++ b/src/ipc_listener.cpp
@@ -151,12 +151,15 @@ int xs::ipc_listener_t::close ()
xs::fd_t xs::ipc_listener_t::accept ()
{
// Accept one connection and deal with different failure modes.
+ // The situation where connection cannot be accepted due to insufficient
+ // resources is considered valid and treated by ignoring the connection.
xs_assert (s != retired_fd);
fd_t sock = ::accept (s, NULL, NULL);
if (sock == -1) {
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINTR || errno == ECONNABORTED || errno == EPROTO ||
- errno == ENOBUFS);
+ errno == ENOBUFS || errno == ENOMEM || errno == EMFILE ||
+ errno == ENFILE);
return retired_fd;
}
return sock;
diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp
index 5e1dcc9..2fda819 100644
--- a/src/tcp_listener.cpp
+++ b/src/tcp_listener.cpp
@@ -198,19 +198,24 @@ int xs::tcp_listener_t::set_address (const char *addr_)
xs::fd_t xs::tcp_listener_t::accept ()
{
// Accept one connection and deal with different failure modes.
+ // The situation where connection cannot be accepted due to insufficient
+ // resources is considered valid and treated by ignoring the connection.
xs_assert (s != retired_fd);
fd_t sock = ::accept (s, NULL, NULL);
#ifdef XS_HAVE_WINDOWS
if (sock == INVALID_SOCKET) {
wsa_assert (WSAGetLastError () == WSAEWOULDBLOCK ||
- WSAGetLastError () == WSAECONNRESET);
+ WSAGetLastError () == WSAECONNRESET ||
+ WSAGetLastError () == WSAEMFILE ||
+ WSAGetLastError () == WSAENOBUFS);
return retired_fd;
}
#else
if (sock == -1) {
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINTR || errno == ECONNABORTED || errno == EPROTO ||
- errno == ENOBUFS);
+ errno == ENOBUFS || errno == ENOMEM || errno == EMFILE ||
+ errno == ENFILE);
return retired_fd;
}
#endif