aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-05-15 10:20:04 +0000
committerChristian Grothoff <christian@grothoff.org>2016-05-15 10:20:04 +0000
commitde6e50d00eacf8895c33351572381948aa5079a3 (patch)
treeef722c26d839f512123ef9e3f696ff7f1b7f0f2b /src/microhttpd/daemon.c
parent2b041aea4e05b11b47e37a38e8294de36ea8db44 (diff)
downloadlibmicrohttpd-de6e50d00eacf8895c33351572381948aa5079a3.tar.gz
libmicrohttpd-de6e50d00eacf8895c33351572381948aa5079a3.zip
handle EMFILE, ENFILE, ENOBUF on accept
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index b8d8a749..b36db043 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2085,6 +2085,28 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
2085 MHD_PANIC ("close failed\n"); 2085 MHD_PANIC ("close failed\n");
2086 /* just in case */ 2086 /* just in case */
2087 } 2087 }
2088 if ( (EMFILE == err) ||
2089 (ENFILE == err) ||
2090 (ENOMEM == err) ||
2091 (ENOBUFS == err) )
2092 {
2093 /* system/process out of resources */
2094 if (0 == daemon->connections)
2095 {
2096 /* Not setting 'at_limit' flag, as there is no way it
2097 would ever be cleared. Instead trying to produce
2098 bit fat ugly warning. */
2099 MHD_DLOG (daemon,
2100 "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n");
2101 }
2102 else
2103 {
2104 daemon->at_limit = MHD_YES;
2105 MHD_DLOG (daemon,
2106 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n",
2107 (unsigned int) daemon->connections);
2108 }
2109 }
2088 return MHD_NO; 2110 return MHD_NO;
2089 } 2111 }
2090#if !defined(USE_ACCEPT4) 2112#if !defined(USE_ACCEPT4)
@@ -2142,6 +2164,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
2142 gnutls_deinit (pos->tls_session); 2164 gnutls_deinit (pos->tls_session);
2143#endif 2165#endif
2144 daemon->connections--; 2166 daemon->connections--;
2167 daemon->at_limit = MHD_NO;
2145 if (NULL != daemon->notify_connection) 2168 if (NULL != daemon->notify_connection)
2146 daemon->notify_connection (daemon->notify_connection_cls, 2169 daemon->notify_connection (daemon->notify_connection_cls,
2147 pos, 2170 pos,
@@ -2420,9 +2443,10 @@ MHD_select (struct MHD_Daemon *daemon,
2420 we do not miss the shutdown, so only do this 2443 we do not miss the shutdown, so only do this
2421 optimization if we have a shutdown signaling 2444 optimization if we have a shutdown signaling
2422 pipe. */ 2445 pipe. */
2423 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2446 if ( ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2424 (daemon->connections == daemon->connection_limit) && 2447 (daemon->connections == daemon->connection_limit) &&
2425 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) ) 2448 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) ) ||
2449 (MHD_YES == daemon->at_limit) )
2426 FD_CLR (daemon->socket_fd, &rs); 2450 FD_CLR (daemon->socket_fd, &rs);
2427 } 2451 }
2428 else 2452 else
@@ -2558,7 +2582,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2558 poll_server = 0; 2582 poll_server = 0;
2559 poll_listen = -1; 2583 poll_listen = -1;
2560 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2584 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2561 (daemon->connections < daemon->connection_limit) ) 2585 (daemon->connections < daemon->connection_limit) &&
2586 (MHD_NO == daemon->at_limit) )
2562 { 2587 {
2563 /* only listen if we are not at the connection limit */ 2588 /* only listen if we are not at the connection limit */
2564 p[poll_server].fd = daemon->socket_fd; 2589 p[poll_server].fd = daemon->socket_fd;
@@ -2794,7 +2819,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
2794 return MHD_NO; 2819 return MHD_NO;
2795 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2820 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2796 (daemon->connections < daemon->connection_limit) && 2821 (daemon->connections < daemon->connection_limit) &&
2797 (MHD_NO == daemon->listen_socket_in_epoll) ) 2822 (MHD_NO == daemon->listen_socket_in_epoll) &&
2823 (MHD_NO == daemon->at_limit) )
2798 { 2824 {
2799 event.events = EPOLLIN; 2825 event.events = EPOLLIN;
2800 event.data.ptr = daemon; 2826 event.data.ptr = daemon;
@@ -2812,8 +2838,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
2812 } 2838 }
2813 daemon->listen_socket_in_epoll = MHD_YES; 2839 daemon->listen_socket_in_epoll = MHD_YES;
2814 } 2840 }
2815 if ( (MHD_YES == daemon->listen_socket_in_epoll) && 2841 if ( ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2816 (daemon->connections == daemon->connection_limit) ) 2842 (daemon->connections == daemon->connection_limit) ) ||
2843 (MHD_YES == daemon->at_limit) )
2817 { 2844 {
2818 /* we're at the connection limit, disable listen socket 2845 /* we're at the connection limit, disable listen socket
2819 for event loop for now */ 2846 for event loop for now */
@@ -2912,7 +2939,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
2912 series_length = 0; 2939 series_length = 0;
2913 while ( (MHD_YES == MHD_accept_connection (daemon)) && 2940 while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2914 (daemon->connections < daemon->connection_limit) && 2941 (daemon->connections < daemon->connection_limit) &&
2915 (series_length < 128) ) 2942 (series_length < 128) &&
2943 (MHD_NO == daemon->at_limit) )
2916 series_length++; 2944 series_length++;
2917 } 2945 }
2918 } 2946 }