From 123c0f5387ecef287dd11f4dc790fb76ee1c0f67 Mon Sep 17 00:00:00 2001
From: Martin Sustrik <sustrik@250bpm.com>
Date: Sat, 7 Apr 2012 19:19:06 +0200
Subject: 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>
---
 src/ipc_listener.cpp | 5 ++++-
 src/tcp_listener.cpp | 9 +++++++--
 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
-- 
cgit v1.2.3