diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-05-15 10:20:04 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-05-15 10:20:04 +0000 |
commit | de6e50d00eacf8895c33351572381948aa5079a3 (patch) | |
tree | ef722c26d839f512123ef9e3f696ff7f1b7f0f2b /src/microhttpd/daemon.c | |
parent | 2b041aea4e05b11b47e37a38e8294de36ea8db44 (diff) | |
download | libmicrohttpd-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.c | 44 |
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 | } |