aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-07-04 15:29:56 +0000
committerChristian Grothoff <christian@grothoff.org>2013-07-04 15:29:56 +0000
commit9fe0e9d41112f2a75ee4d9461f1b93b59131029d (patch)
tree1744c5d4172917dcd38002e67baa095db95a0215 /src
parent21f9a70d53a472e0c3894099308ca040d401209a (diff)
downloadlibmicrohttpd-9fe0e9d41112f2a75ee4d9461f1b93b59131029d.tar.gz
libmicrohttpd-9fe0e9d41112f2a75ee4d9461f1b93b59131029d.zip
Adding support for using epoll for the MHD event loop
Diffstat (limited to 'src')
-rw-r--r--src/include/microhttpd.h14
-rw-r--r--src/microhttpd/connection.c297
-rw-r--r--src/microhttpd/connection.h32
-rw-r--r--src/microhttpd/daemon.c1149
-rw-r--r--src/microhttpd/internal.h285
-rw-r--r--src/microhttpd/memorypool.c9
-rw-r--r--src/testcurl/Makefile.am4
-rw-r--r--src/testcurl/perf_get.c13
-rw-r--r--src/testcurl/perf_get_concurrent.c4
-rw-r--r--src/testcurl/test_get.c9
-rw-r--r--src/testcurl/test_quiesce.c76
-rw-r--r--src/testcurl/test_start_stop.c4
12 files changed, 1410 insertions, 486 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 5c87c721..318a8424 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -356,8 +356,11 @@ enum MHD_FLAG
356 MHD_USE_SELECT_INTERNALLY = 8, 356 MHD_USE_SELECT_INTERNALLY = 8,
357 357
358 /** 358 /**
359 * Run using the IPv6 protocol (otherwise, MHD will 359 * Run using the IPv6 protocol (otherwise, MHD will just support
360 * just support IPv4). 360 * IPv4). If you want MHD to support IPv4 and IPv6 using a single
361 * socket, pass MHD_USE_DUAL_STACK, otherwise, if you only pass
362 * this option, MHD will try to bind to IPv6-only (resulting in
363 * no IPv4 support).
361 */ 364 */
362 MHD_USE_IPv6 = 16, 365 MHD_USE_IPv6 = 16,
363 366
@@ -428,7 +431,12 @@ enum MHD_FLAG
428 * specify it), if 'MHD_USE_NO_LISTEN_SOCKET' is specified. In 431 * specify it), if 'MHD_USE_NO_LISTEN_SOCKET' is specified. In
429 * "external" select mode, this option is always simply ignored. 432 * "external" select mode, this option is always simply ignored.
430 */ 433 */
431 MHD_USE_PIPE_FOR_SHUTDOWN = 1024 434 MHD_USE_PIPE_FOR_SHUTDOWN = 1024,
435
436 /**
437 * Use a single socket for IPv4 and IPv6.
438 */
439 MHD_USE_DUAL_STACK = MHD_USE_IPv6 | 2048
432 440
433}; 441};
434 442
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 4d651a39..e54ae1b6 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -318,8 +318,9 @@ MHD_connection_close (struct MHD_Connection *connection,
318 318
319 daemon = connection->daemon; 319 daemon = connection->daemon;
320 SHUTDOWN (connection->socket_fd, 320 SHUTDOWN (connection->socket_fd,
321 (connection->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR); 321 (MHD_YES == connection->read_closed) ? SHUT_WR : SHUT_RDWR);
322 connection->state = MHD_CONNECTION_CLOSED; 322 connection->state = MHD_CONNECTION_CLOSED;
323 connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
323 if ( (NULL != daemon->notify_completed) && 324 if ( (NULL != daemon->notify_completed) &&
324 (MHD_YES == connection->client_aware) ) 325 (MHD_YES == connection->client_aware) )
325 daemon->notify_completed (daemon->notify_completed_cls, 326 daemon->notify_completed (daemon->notify_completed_cls,
@@ -745,8 +746,8 @@ build_header_response (struct MHD_Connection *connection)
745 kind = MHD_FOOTER_KIND; 746 kind = MHD_FOOTER_KIND;
746 off = 0; 747 off = 0;
747 } 748 }
748 must_add_close = ( (connection->state == MHD_CONNECTION_FOOTERS_RECEIVED) && 749 must_add_close = ( (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state) &&
749 (connection->read_closed == MHD_YES) && 750 (MHD_YES == connection->read_closed) &&
750 (0 == strcasecmp (connection->version, 751 (0 == strcasecmp (connection->version,
751 MHD_HTTP_VERSION_1_1)) && 752 MHD_HTTP_VERSION_1_1)) &&
752 (NULL == MHD_get_response_header (connection->response, 753 (NULL == MHD_get_response_header (connection->response,
@@ -853,87 +854,16 @@ transmit_error_response (struct MHD_Connection *connection,
853 854
854 855
855/** 856/**
856 * Add "fd" to the "fd_set". If "fd" is 857 * Update the 'event_loop_info' field of this connection based on the state
857 * greater than "*max", set "*max" to fd. 858 * that the connection is now in. May also close the connection or
858 * 859 * perform other updates to the connection if needed to prepare for
859 * @param fd file descriptor to add to the set 860 * the next round of the event loop.
860 * @param set set to modify
861 * @param max_fd maximum value to potentially update
862 */
863static void
864add_to_fd_set (int fd,
865 fd_set *set,
866 int *max_fd)
867{
868 FD_SET (fd, set);
869 if ( (NULL != max_fd) &&
870 (fd > *max_fd) )
871 *max_fd = fd;
872}
873
874
875/**
876 * Obtain the select sets for this connection. The given
877 * sets (and the maximum) are updated and must have
878 * already been initialized.
879 *
880 * @param connection connetion to get select sets for
881 * @param read_fd_set read set to initialize
882 * @param write_fd_set write set to initialize
883 * @param except_fd_set except set to initialize (never changed)
884 * @param max_fd where to store largest FD put into any set
885 * @return MHD_YES on success
886 */
887int
888MHD_connection_get_fdset (struct MHD_Connection *connection,
889 fd_set *read_fd_set,
890 fd_set *write_fd_set,
891 fd_set *except_fd_set,
892 int *max_fd)
893{
894 int ret;
895 struct MHD_Pollfd p;
896
897 /* we use the 'poll fd' as a convenient way to re-use code
898 when determining the select sets */
899 memset (&p, 0, sizeof(struct MHD_Pollfd));
900 ret = MHD_connection_get_pollfd (connection, &p);
901 if ( (MHD_YES == ret) && (p.fd >= 0) ) {
902 if (0 != (p.events & MHD_POLL_ACTION_IN))
903 add_to_fd_set(p.fd, read_fd_set, max_fd);
904 if (0 != (p.events & MHD_POLL_ACTION_OUT))
905 add_to_fd_set(p.fd, write_fd_set, max_fd);
906 }
907 return ret;
908}
909
910
911/**
912 * Obtain the pollfd for this connection
913 * 861 *
914 * @param connection connetion to get poll set for 862 * @param connection connetion to get poll set for
915 * @param p where to store the polling information
916 * @return MHD_YES on success. If return MHD_YES and p->fd < 0, this
917 * connection is not waiting for any read or write events
918 */ 863 */
919int 864static void
920MHD_connection_get_pollfd (struct MHD_Connection *connection, 865MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
921 struct MHD_Pollfd *p)
922{ 866{
923 int fd;
924
925 if (NULL == connection->pool)
926 connection->pool = MHD_pool_create (connection->daemon->pool_size);
927 if (NULL == connection->pool)
928 {
929 CONNECTION_CLOSE_ERROR (connection,
930 "Failed to create memory pool!\n");
931 return MHD_YES;
932 }
933 fd = connection->socket_fd;
934 p->fd = fd;
935 if (-1 == fd)
936 return MHD_YES;
937 while (1) 867 while (1)
938 { 868 {
939#if DEBUG_STATES 869#if DEBUG_STATES
@@ -945,9 +875,9 @@ MHD_connection_get_pollfd (struct MHD_Connection *connection,
945#if HTTPS_SUPPORT 875#if HTTPS_SUPPORT
946 case MHD_TLS_CONNECTION_INIT: 876 case MHD_TLS_CONNECTION_INIT:
947 if (0 == gnutls_record_get_direction (connection->tls_session)) 877 if (0 == gnutls_record_get_direction (connection->tls_session))
948 p->events |= MHD_POLL_ACTION_IN; 878 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
949 else 879 else
950 p->events |= MHD_POLL_ACTION_OUT; 880 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
951 break; 881 break;
952#endif 882#endif
953 case MHD_CONNECTION_INIT: 883 case MHD_CONNECTION_INIT:
@@ -955,15 +885,8 @@ MHD_connection_get_pollfd (struct MHD_Connection *connection,
955 case MHD_CONNECTION_HEADER_PART_RECEIVED: 885 case MHD_CONNECTION_HEADER_PART_RECEIVED:
956 /* while reading headers, we always grow the 886 /* while reading headers, we always grow the
957 read buffer if needed, no size-check required */ 887 read buffer if needed, no size-check required */
958 if ((connection->read_closed) && 888 if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
959 (0 == connection->read_buffer_offset)) 889 (MHD_NO == try_grow_read_buffer (connection)) )
960 {
961 CONNECTION_CLOSE_ERROR (connection,
962 "Connection buffer to small for request\n");
963 continue;
964 }
965 if ((connection->read_buffer_offset == connection->read_buffer_size)
966 && (MHD_NO == try_grow_read_buffer (connection)))
967 { 890 {
968 transmit_error_response (connection, 891 transmit_error_response (connection,
969 (connection->url != NULL) 892 (connection->url != NULL)
@@ -972,18 +895,19 @@ MHD_connection_get_pollfd (struct MHD_Connection *connection,
972 REQUEST_TOO_BIG); 895 REQUEST_TOO_BIG);
973 continue; 896 continue;
974 } 897 }
975 if (MHD_NO == connection->read_closed) 898 if (MHD_NO == connection->read_closed)
976 p->events |= MHD_POLL_ACTION_IN; 899 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
900 else
901 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
977 break; 902 break;
978 case MHD_CONNECTION_HEADERS_RECEIVED: 903 case MHD_CONNECTION_HEADERS_RECEIVED:
979 /* we should never get here */
980 EXTRA_CHECK (0); 904 EXTRA_CHECK (0);
981 break; 905 break;
982 case MHD_CONNECTION_HEADERS_PROCESSED: 906 case MHD_CONNECTION_HEADERS_PROCESSED:
983 EXTRA_CHECK (0); 907 EXTRA_CHECK (0);
984 break; 908 break;
985 case MHD_CONNECTION_CONTINUE_SENDING: 909 case MHD_CONNECTION_CONTINUE_SENDING:
986 p->events |= MHD_POLL_ACTION_OUT; 910 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
987 break; 911 break;
988 case MHD_CONNECTION_CONTINUE_SENT: 912 case MHD_CONNECTION_CONTINUE_SENT:
989 if (connection->read_buffer_offset == connection->read_buffer_size) 913 if (connection->read_buffer_offset == connection->read_buffer_size)
@@ -1010,9 +934,11 @@ MHD_connection_get_pollfd (struct MHD_Connection *connection,
1010 continue; 934 continue;
1011 } 935 }
1012 } 936 }
1013 if ((connection->read_buffer_offset < connection->read_buffer_size) 937 if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
1014 && (MHD_NO == connection->read_closed)) 938 (MHD_NO == connection->read_closed) )
1015 p->events |= MHD_POLL_ACTION_IN; 939 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
940 else
941 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1016 break; 942 break;
1017 case MHD_CONNECTION_BODY_RECEIVED: 943 case MHD_CONNECTION_BODY_RECEIVED:
1018 case MHD_CONNECTION_FOOTER_PART_RECEIVED: 944 case MHD_CONNECTION_FOOTER_PART_RECEIVED:
@@ -1024,50 +950,49 @@ MHD_connection_get_pollfd (struct MHD_Connection *connection,
1024 NULL); 950 NULL);
1025 continue; 951 continue;
1026 } 952 }
1027 p->events |= MHD_POLL_ACTION_IN; 953 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1028 /* transition to FOOTERS_RECEIVED 954 /* transition to FOOTERS_RECEIVED
1029 happens in read handler */ 955 happens in read handler */
1030 break; 956 break;
1031 case MHD_CONNECTION_FOOTERS_RECEIVED: 957 case MHD_CONNECTION_FOOTERS_RECEIVED:
1032 /* no socket action, wait for client 958 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1033 to provide response */
1034 break; 959 break;
1035 case MHD_CONNECTION_HEADERS_SENDING: 960 case MHD_CONNECTION_HEADERS_SENDING:
1036 /* headers in buffer, keep writing */ 961 /* headers in buffer, keep writing */
1037 p->events |= MHD_POLL_ACTION_OUT; 962 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1038 break; 963 break;
1039 case MHD_CONNECTION_HEADERS_SENT: 964 case MHD_CONNECTION_HEADERS_SENT:
1040 EXTRA_CHECK (0); 965 EXTRA_CHECK (0);
1041 break; 966 break;
1042 case MHD_CONNECTION_NORMAL_BODY_READY: 967 case MHD_CONNECTION_NORMAL_BODY_READY:
1043 p->events |= MHD_POLL_ACTION_OUT; 968 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1044 break; 969 break;
1045 case MHD_CONNECTION_NORMAL_BODY_UNREADY: 970 case MHD_CONNECTION_NORMAL_BODY_UNREADY:
1046 /* not ready, no socket action */ 971 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1047 break; 972 break;
1048 case MHD_CONNECTION_CHUNKED_BODY_READY: 973 case MHD_CONNECTION_CHUNKED_BODY_READY:
1049 p->events |= MHD_POLL_ACTION_OUT; 974 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1050 break; 975 break;
1051 case MHD_CONNECTION_CHUNKED_BODY_UNREADY: 976 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
1052 /* not ready, no socket action */ 977 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1053 break; 978 break;
1054 case MHD_CONNECTION_BODY_SENT: 979 case MHD_CONNECTION_BODY_SENT:
1055 EXTRA_CHECK (0); 980 EXTRA_CHECK (0);
1056 break; 981 break;
1057 case MHD_CONNECTION_FOOTERS_SENDING: 982 case MHD_CONNECTION_FOOTERS_SENDING:
1058 p->events |= MHD_POLL_ACTION_OUT; 983 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1059 break; 984 break;
1060 case MHD_CONNECTION_FOOTERS_SENT: 985 case MHD_CONNECTION_FOOTERS_SENT:
1061 EXTRA_CHECK (0); 986 EXTRA_CHECK (0);
1062 break; 987 break;
1063 case MHD_CONNECTION_CLOSED: 988 case MHD_CONNECTION_CLOSED:
1064 return MHD_YES; /* do nothing, not even reading */ 989 connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
990 return; /* do nothing, not even reading */
1065 default: 991 default:
1066 EXTRA_CHECK (0); 992 EXTRA_CHECK (0);
1067 } 993 }
1068 break; 994 break;
1069 } 995 }
1070 return MHD_YES;
1071} 996}
1072 997
1073 998
@@ -1888,10 +1813,41 @@ parse_connection_headers (struct MHD_Connection *connection)
1888 1813
1889 1814
1890/** 1815/**
1816 * Update the 'last_activity' field of the connection to the current time
1817 * and move the connection to the head of the 'normal_timeout' list if
1818 * the timeout for the connection uses the default value.
1819 *
1820 * @param connection the connection that saw some activity
1821 */
1822static void
1823update_last_activity (struct MHD_Connection *connection)
1824{
1825 struct MHD_Daemon *daemon = connection->daemon;
1826
1827 connection->last_activity = MHD_monotonic_time();
1828 if (connection->connection_timeout != daemon->connection_timeout)
1829 return; /* custom timeout, no need to move it in DLL */
1830
1831 /* move connection to head of timeout list (by remove + add operation) */
1832 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1833 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1834 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1835 XDLL_remove (daemon->normal_timeout_head,
1836 daemon->normal_timeout_tail,
1837 connection);
1838 XDLL_insert (daemon->normal_timeout_head,
1839 daemon->normal_timeout_tail,
1840 connection);
1841 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1842 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1843 MHD_PANIC ("Failed to release cleanup mutex\n");
1844}
1845
1846
1847
1848/**
1891 * This function handles a particular connection when it has been 1849 * This function handles a particular connection when it has been
1892 * determined that there is data to be read off a socket. All 1850 * determined that there is data to be read off a socket.
1893 * implementations (multithreaded, external select, internal select)
1894 * call this function to handle reads.
1895 * 1851 *
1896 * @param connection connection to handle 1852 * @param connection connection to handle
1897 * @return always MHD_YES (we should continue to process the 1853 * @return always MHD_YES (we should continue to process the
@@ -1900,7 +1856,7 @@ parse_connection_headers (struct MHD_Connection *connection)
1900int 1856int
1901MHD_connection_handle_read (struct MHD_Connection *connection) 1857MHD_connection_handle_read (struct MHD_Connection *connection)
1902{ 1858{
1903 connection->last_activity = MHD_monotonic_time(); 1859 update_last_activity (connection);
1904 if (connection->state == MHD_CONNECTION_CLOSED) 1860 if (connection->state == MHD_CONNECTION_CLOSED)
1905 return MHD_YES; 1861 return MHD_YES;
1906 /* make sure "read" has a reasonable number of bytes 1862 /* make sure "read" has a reasonable number of bytes
@@ -1953,9 +1909,7 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
1953 1909
1954/** 1910/**
1955 * This function was created to handle writes to sockets when it has 1911 * This function was created to handle writes to sockets when it has
1956 * been determined that the socket can be written to. All 1912 * been determined that the socket can be written to.
1957 * implementations (multithreaded, external select, internal select)
1958 * call this function
1959 * 1913 *
1960 * @param connection connection to handle 1914 * @param connection connection to handle
1961 * @return always MHD_YES (we should continue to process the 1915 * @return always MHD_YES (we should continue to process the
@@ -1966,7 +1920,8 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
1966{ 1920{
1967 struct MHD_Response *response; 1921 struct MHD_Response *response;
1968 int ret; 1922 int ret;
1969 connection->last_activity = MHD_monotonic_time(); 1923
1924 update_last_activity (connection);
1970 while (1) 1925 while (1)
1971 { 1926 {
1972#if DEBUG_STATES 1927#if DEBUG_STATES
@@ -2111,9 +2066,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2111 2066
2112/** 2067/**
2113 * This function was created to handle per-connection processing that 2068 * This function was created to handle per-connection processing that
2114 * has to happen even if the socket cannot be read or written to. All 2069 * has to happen even if the socket cannot be read or written to.
2115 * implementations (multithreaded, external select, internal select)
2116 * call this function.
2117 * 2070 *
2118 * @param connection connection to handle 2071 * @param connection connection to handle
2119 * @return MHD_YES if we should continue to process the 2072 * @return MHD_YES if we should continue to process the
@@ -2122,7 +2075,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2122int 2075int
2123MHD_connection_handle_idle (struct MHD_Connection *connection) 2076MHD_connection_handle_idle (struct MHD_Connection *connection)
2124{ 2077{
2125 struct MHD_Daemon *daemon; 2078 struct MHD_Daemon *daemon = connection->daemon;
2126 unsigned int timeout; 2079 unsigned int timeout;
2127 const char *end; 2080 const char *end;
2128 int rend; 2081 int rend;
@@ -2131,18 +2084,18 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2131 while (1) 2084 while (1)
2132 { 2085 {
2133#if DEBUG_STATES 2086#if DEBUG_STATES
2134 MHD_DLOG (connection->daemon, "%s: state: %s\n", 2087 MHD_DLOG (daemon, "%s: state: %s\n",
2135 __FUNCTION__, MHD_state_to_string (connection->state)); 2088 __FUNCTION__, MHD_state_to_string (connection->state));
2136#endif 2089#endif
2137 switch (connection->state) 2090 switch (connection->state)
2138 { 2091 {
2139 case MHD_CONNECTION_INIT: 2092 case MHD_CONNECTION_INIT:
2140 line = get_next_header_line (connection); 2093 line = get_next_header_line (connection);
2141 if (line == NULL) 2094 if (NULL == line)
2142 { 2095 {
2143 if (connection->state != MHD_CONNECTION_INIT) 2096 if (MHD_CONNECTION_INIT != connection->state)
2144 continue; 2097 continue;
2145 if (connection->read_closed) 2098 if (MHD_YES == connection->read_closed)
2146 { 2099 {
2147 CONNECTION_CLOSE_ERROR (connection, 2100 CONNECTION_CLOSE_ERROR (connection,
2148 NULL); 2101 NULL);
@@ -2159,9 +2112,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2159 line = get_next_header_line (connection); 2112 line = get_next_header_line (connection);
2160 if (line == NULL) 2113 if (line == NULL)
2161 { 2114 {
2162 if (connection->state != MHD_CONNECTION_URL_RECEIVED) 2115 if (MHD_CONNECTION_URL_RECEIVED != connection->state)
2163 continue; 2116 continue;
2164 if (connection->read_closed) 2117 if (MHD_YES == connection->read_closed)
2165 { 2118 {
2166 CONNECTION_CLOSE_ERROR (connection, 2119 CONNECTION_CLOSE_ERROR (connection,
2167 NULL); 2120 NULL);
@@ -2189,7 +2142,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2189 { 2142 {
2190 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED) 2143 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
2191 continue; 2144 continue;
2192 if (connection->read_closed) 2145 if (MHD_YES == connection->read_closed)
2193 { 2146 {
2194 CONNECTION_CLOSE_ERROR (connection, 2147 CONNECTION_CLOSE_ERROR (connection,
2195 NULL); 2148 NULL);
@@ -2232,7 +2185,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2232 /* force close, in case client still tries to upload... */ 2185 /* force close, in case client still tries to upload... */
2233 connection->read_closed = MHD_YES; 2186 connection->read_closed = MHD_YES;
2234 } 2187 }
2235 connection->state = (connection->remaining_upload_size == 0) 2188 connection->state = (0 == connection->remaining_upload_size)
2236 ? MHD_CONNECTION_FOOTERS_RECEIVED : MHD_CONNECTION_CONTINUE_SENT; 2189 ? MHD_CONNECTION_FOOTERS_RECEIVED : MHD_CONNECTION_CONTINUE_SENT;
2237 continue; 2190 continue;
2238 case MHD_CONNECTION_CONTINUE_SENDING: 2191 case MHD_CONNECTION_CONTINUE_SENDING:
@@ -2269,7 +2222,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2269 { 2222 {
2270 if (connection->state != MHD_CONNECTION_BODY_RECEIVED) 2223 if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
2271 continue; 2224 continue;
2272 if (connection->read_closed) 2225 if (MHD_YES == connection->read_closed)
2273 { 2226 {
2274 CONNECTION_CLOSE_ERROR (connection, 2227 CONNECTION_CLOSE_ERROR (connection,
2275 NULL); 2228 NULL);
@@ -2297,7 +2250,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2297 { 2250 {
2298 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED) 2251 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
2299 continue; 2252 continue;
2300 if (connection->read_closed) 2253 if (MHD_YES == connection->read_closed)
2301 { 2254 {
2302 CONNECTION_CLOSE_ERROR (connection, 2255 CONNECTION_CLOSE_ERROR (connection,
2303 NULL); 2256 NULL);
@@ -2421,11 +2374,10 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2421 ( (end != NULL) && (0 == strcasecmp (end, "close")) ) ); 2374 ( (end != NULL) && (0 == strcasecmp (end, "close")) ) );
2422 MHD_destroy_response (connection->response); 2375 MHD_destroy_response (connection->response);
2423 connection->response = NULL; 2376 connection->response = NULL;
2424 if (connection->daemon->notify_completed != NULL) 2377 if (daemon->notify_completed != NULL)
2425 connection->daemon->notify_completed (connection->daemon-> 2378 daemon->notify_completed (daemon->notify_completed_cls,
2426 notify_completed_cls, 2379 connection,
2427 connection, 2380 &connection->client_context,
2428 &connection->client_context,
2429 MHD_REQUEST_TERMINATED_COMPLETED_OK); 2381 MHD_REQUEST_TERMINATED_COMPLETED_OK);
2430 connection->client_aware = MHD_NO; 2382 connection->client_aware = MHD_NO;
2431 end = 2383 end =
@@ -2478,21 +2430,26 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2478 MHD_destroy_response (connection->response); 2430 MHD_destroy_response (connection->response);
2479 connection->response = NULL; 2431 connection->response = NULL;
2480 } 2432 }
2481 daemon = connection->daemon; 2433 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2482 if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) 2434 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
2483 { 2435 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2484 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 2436 if (connection->connection_timeout == daemon->connection_timeout)
2485 } 2437 XDLL_remove (daemon->normal_timeout_head,
2438 daemon->normal_timeout_tail,
2439 connection);
2440 else
2441 XDLL_remove (daemon->manual_timeout_head,
2442 daemon->manual_timeout_tail,
2443 connection);
2486 DLL_remove (daemon->connections_head, 2444 DLL_remove (daemon->connections_head,
2487 daemon->connections_tail, 2445 daemon->connections_tail,
2488 connection); 2446 connection);
2489 DLL_insert (daemon->cleanup_head, 2447 DLL_insert (daemon->cleanup_head,
2490 daemon->cleanup_tail, 2448 daemon->cleanup_tail,
2491 connection); 2449 connection);
2492 if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) 2450 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2493 { 2451 (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) )
2494 MHD_PANIC ("Failed to release cleanup mutex\n"); 2452 MHD_PANIC ("Failed to release cleanup mutex\n");
2495 }
2496 return MHD_NO; 2453 return MHD_NO;
2497 default: 2454 default:
2498 EXTRA_CHECK (0); 2455 EXTRA_CHECK (0);
@@ -2507,6 +2464,32 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2507 MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); 2464 MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
2508 return MHD_YES; 2465 return MHD_YES;
2509 } 2466 }
2467 MHD_connection_update_event_loop_info (connection);
2468 switch (connection->event_loop_info)
2469 {
2470 case MHD_EVENT_LOOP_INFO_READ:
2471 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY))
2472 EDLL_insert (daemon->eready_head,
2473 daemon->eready_tail,
2474 connection);
2475 break;
2476 case MHD_EVENT_LOOP_INFO_WRITE:
2477 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))
2478 EDLL_insert (daemon->eready_head,
2479 daemon->eready_tail,
2480 connection);
2481 break;
2482 case MHD_EVENT_LOOP_INFO_BLOCK:
2483 /* we should look at this connection again in the next iteration
2484 of the event loop, as we're waiting on the application */
2485 EDLL_insert (daemon->eready_head,
2486 daemon->eready_tail,
2487 connection);
2488 break;
2489 case MHD_EVENT_LOOP_INFO_CLEANUP:
2490 /* This connection is finished, nothing left to do */
2491 break;
2492 }
2510 return MHD_YES; 2493 return MHD_YES;
2511} 2494}
2512 2495
@@ -2582,13 +2565,37 @@ MHD_set_connection_option (struct MHD_Connection *connection,
2582 ...) 2565 ...)
2583{ 2566{
2584 va_list ap; 2567 va_list ap;
2568 struct MHD_Daemon *daemon;
2585 2569
2570 daemon = connection->daemon;
2586 switch (option) 2571 switch (option)
2587 { 2572 {
2588 case MHD_CONNECTION_OPTION_TIMEOUT: 2573 case MHD_CONNECTION_OPTION_TIMEOUT:
2574 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2575 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
2576 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2577 if (connection->connection_timeout == daemon->connection_timeout)
2578 XDLL_remove (daemon->normal_timeout_head,
2579 daemon->normal_timeout_tail,
2580 connection);
2581 else
2582 XDLL_remove (daemon->manual_timeout_head,
2583 daemon->manual_timeout_tail,
2584 connection);
2589 va_start (ap, option); 2585 va_start (ap, option);
2590 connection->connection_timeout = va_arg (ap, unsigned int); 2586 connection->connection_timeout = va_arg (ap, unsigned int);
2591 va_end (ap); 2587 va_end (ap);
2588 if (connection->connection_timeout == daemon->connection_timeout)
2589 XDLL_insert (daemon->normal_timeout_head,
2590 daemon->normal_timeout_tail,
2591 connection);
2592 else
2593 XDLL_insert (daemon->manual_timeout_head,
2594 daemon->manual_timeout_tail,
2595 connection);
2596 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2597 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
2598 MHD_PANIC ("Failed to release cleanup mutex\n");
2592 return MHD_YES; 2599 return MHD_YES;
2593 default: 2600 default:
2594 return MHD_NO; 2601 return MHD_NO;
diff --git a/src/microhttpd/connection.h b/src/microhttpd/connection.h
index e639691f..985f29ed 100644
--- a/src/microhttpd/connection.h
+++ b/src/microhttpd/connection.h
@@ -31,38 +31,6 @@
31 31
32 32
33/** 33/**
34 * Obtain the select sets for this connection. The given
35 * sets (and the maximum) are updated and must have
36 * already been initialized.
37 *
38 * @param connection connetion to get select sets for
39 * @param read_fd_set read set to initialize
40 * @param write_fd_set write set to initialize
41 * @param except_fd_set except set to initialize (never changed)
42 * @param max_fd where to store largest FD put into any set
43 * @return MHD_YES on success
44 */
45int
46MHD_connection_get_fdset (struct MHD_Connection *connection,
47 fd_set * read_fd_set,
48 fd_set * write_fd_set,
49 fd_set * except_fd_set, int *max_fd);
50
51
52/**
53 * Obtain the pollfd for this connection. The poll interface allows large
54 * file descriptors. Select goes stupid when the fd overflows fdset (which
55 * is fixed).
56 *
57 * @param connection connetion to get poll set for
58 * @param p where to store the polling information
59 */
60int
61MHD_connection_get_pollfd (struct MHD_Connection *connection,
62 struct MHD_Pollfd *p);
63
64
65/**
66 * Set callbacks for this connection to those for HTTP. 34 * Set callbacks for this connection to those for HTTP.
67 * 35 *
68 * @param connection connection to initialize 36 * @param connection connection to initialize
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index ef69d14b..28ce1d80 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 (C) 2007, 2008, 2009, 2010, 2011, 2012 Daniel Pittman and Christian Grothoff 3 (C) 2007-2013 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -39,7 +39,6 @@
39 39
40#if HTTPS_SUPPORT 40#if HTTPS_SUPPORT
41#include "connection_https.h" 41#include "connection_https.h"
42#include <gnutls/gnutls.h>
43#include <gcrypt.h> 42#include <gcrypt.h>
44#endif 43#endif
45 44
@@ -178,7 +177,7 @@ struct MHD_IPCount
178 * @param daemon handle to daemon where lock is 177 * @param daemon handle to daemon where lock is
179 */ 178 */
180static void 179static void
181MHD_ip_count_lock(struct MHD_Daemon *daemon) 180MHD_ip_count_lock (struct MHD_Daemon *daemon)
182{ 181{
183 if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex)) 182 if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex))
184 { 183 {
@@ -193,7 +192,7 @@ MHD_ip_count_lock(struct MHD_Daemon *daemon)
193 * @param daemon handle to daemon where lock is 192 * @param daemon handle to daemon where lock is
194 */ 193 */
195static void 194static void
196MHD_ip_count_unlock(struct MHD_Daemon *daemon) 195MHD_ip_count_unlock (struct MHD_Daemon *daemon)
197{ 196{
198 if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex)) 197 if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex))
199 { 198 {
@@ -212,7 +211,7 @@ MHD_ip_count_unlock(struct MHD_Daemon *daemon)
212 * @return -1, 0 or 1 depending on result of compare 211 * @return -1, 0 or 1 depending on result of compare
213 */ 212 */
214static int 213static int
215MHD_ip_addr_compare(const void *a1, const void *a2) 214MHD_ip_addr_compare (const void *a1, const void *a2)
216{ 215{
217 return memcmp (a1, a2, offsetof (struct MHD_IPCount, count)); 216 return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
218} 217}
@@ -227,9 +226,9 @@ MHD_ip_addr_compare(const void *a1, const void *a2)
227 * @return MHD_YES on success and MHD_NO otherwise (e.g., invalid address type) 226 * @return MHD_YES on success and MHD_NO otherwise (e.g., invalid address type)
228 */ 227 */
229static int 228static int
230MHD_ip_addr_to_key(const struct sockaddr *addr, 229MHD_ip_addr_to_key (const struct sockaddr *addr,
231 socklen_t addrlen, 230 socklen_t addrlen,
232 struct MHD_IPCount *key) 231 struct MHD_IPCount *key)
233{ 232{
234 memset(key, 0, sizeof(*key)); 233 memset(key, 0, sizeof(*key));
235 234
@@ -268,9 +267,9 @@ MHD_ip_addr_to_key(const struct sockaddr *addr,
268 * Also returns MHD_NO if fails to allocate memory. 267 * Also returns MHD_NO if fails to allocate memory.
269 */ 268 */
270static int 269static int
271MHD_ip_limit_add(struct MHD_Daemon *daemon, 270MHD_ip_limit_add (struct MHD_Daemon *daemon,
272 const struct sockaddr *addr, 271 const struct sockaddr *addr,
273 socklen_t addrlen) 272 socklen_t addrlen)
274{ 273{
275 struct MHD_IPCount *key; 274 struct MHD_IPCount *key;
276 void **nodep; 275 void **nodep;
@@ -332,9 +331,9 @@ MHD_ip_limit_add(struct MHD_Daemon *daemon,
332 * @param addrlen number of bytes in addr 331 * @param addrlen number of bytes in addr
333 */ 332 */
334static void 333static void
335MHD_ip_limit_del(struct MHD_Daemon *daemon, 334MHD_ip_limit_del (struct MHD_Daemon *daemon,
336 const struct sockaddr *addr, 335 const struct sockaddr *addr,
337 socklen_t addrlen) 336 socklen_t addrlen)
338{ 337{
339 struct MHD_IPCount search_key; 338 struct MHD_IPCount search_key;
340 struct MHD_IPCount *found_key; 339 struct MHD_IPCount *found_key;
@@ -392,7 +391,11 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
392{ 391{
393 int res; 392 int res;
394 393
395 connection->tls_read_ready = MHD_NO; 394 if (MHD_YES == connection->tls_read_ready)
395 {
396 connection->daemon->num_tls_read_ready--;
397 connection->tls_read_ready = MHD_NO;
398 }
396 res = gnutls_record_recv (connection->tls_session, other, i); 399 res = gnutls_record_recv (connection->tls_session, other, i);
397 if ( (GNUTLS_E_AGAIN == res) || 400 if ( (GNUTLS_E_AGAIN == res) ||
398 (GNUTLS_E_INTERRUPTED == res) ) 401 (GNUTLS_E_INTERRUPTED == res) )
@@ -404,12 +407,15 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
404 { 407 {
405 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication 408 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
406 disrupted); set errno to something caller will interpret 409 disrupted); set errno to something caller will interpret
407 correctly as a hard error*/ 410 correctly as a hard error */
408 errno = EPIPE; 411 errno = EPIPE;
409 return res; 412 return res;
410 } 413 }
411 if (res == i) 414 if (res == i)
412 connection->tls_read_ready = MHD_YES; 415 {
416 connection->tls_read_ready = MHD_YES;
417 connection->daemon->num_tls_read_ready++;
418 }
413 return res; 419 return res;
414} 420}
415 421
@@ -515,6 +521,26 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
515 521
516 522
517/** 523/**
524 * Add "fd" to the "fd_set". If "fd" is
525 * greater than "*max", set "*max" to fd.
526 *
527 * @param fd file descriptor to add to the set
528 * @param set set to modify
529 * @param max_fd maximum value to potentially update
530 */
531static void
532add_to_fd_set (int fd,
533 fd_set *set,
534 int *max_fd)
535{
536 FD_SET (fd, set);
537 if ( (NULL != max_fd) &&
538 (fd > *max_fd) )
539 *max_fd = fd;
540}
541
542
543/**
518 * Obtain the select sets for this daemon. 544 * Obtain the select sets for this daemon.
519 * 545 *
520 * @param daemon daemon to get sets from 546 * @param daemon daemon to get sets from
@@ -546,6 +572,20 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
546 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 572 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
547 || (0 != (daemon->options & MHD_USE_POLL))) 573 || (0 != (daemon->options & MHD_USE_POLL)))
548 return MHD_NO; 574 return MHD_NO;
575#if EPOLL_SUPPORT
576 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
577 {
578 /* we're in epoll mode, use the epoll FD as a stand-in for
579 the entire event set */
580
581 if (daemon->epoll_fd >= FD_SETSIZE)
582 return MHD_NO; /* poll fd too big, fail hard */
583 FD_SET (daemon->epoll_fd, read_fd_set);
584 if ((*max_fd) < daemon->epoll_fd)
585 *max_fd = daemon->epoll_fd;
586 return MHD_YES;
587 }
588#endif
549 fd = daemon->socket_fd; 589 fd = daemon->socket_fd;
550 if (-1 != fd) 590 if (-1 != fd)
551 { 591 {
@@ -555,11 +595,23 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
555 *max_fd = fd; 595 *max_fd = fd;
556 } 596 }
557 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 597 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
558 if (MHD_YES != MHD_connection_get_fdset (pos, 598 {
559 read_fd_set, 599 switch (pos->event_loop_info)
560 write_fd_set, 600 {
561 except_fd_set, max_fd)) 601 case MHD_EVENT_LOOP_INFO_READ:
562 return MHD_NO; 602 add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
603 break;
604 case MHD_EVENT_LOOP_INFO_WRITE:
605 add_to_fd_set (pos->socket_fd, write_fd_set, max_fd);
606 break;
607 case MHD_EVENT_LOOP_INFO_BLOCK:
608 /* not in any FD set */
609 break;
610 case MHD_EVENT_LOOP_INFO_CLEANUP:
611 /* this should never happen */
612 break;
613 }
614 }
563#if DEBUG_CONNECT 615#if DEBUG_CONNECT
564 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd); 616 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
565#endif 617#endif
@@ -581,14 +633,12 @@ MHD_handle_connection (void *data)
581 int num_ready; 633 int num_ready;
582 fd_set rs; 634 fd_set rs;
583 fd_set ws; 635 fd_set ws;
584 fd_set es;
585 int max; 636 int max;
586 struct timeval tv; 637 struct timeval tv;
587 struct timeval *tvp; 638 struct timeval *tvp;
588 unsigned int timeout; 639 unsigned int timeout;
589 time_t now; 640 time_t now;
590#ifdef HAVE_POLL_H 641#ifdef HAVE_POLL_H
591 struct MHD_Pollfd mp;
592 struct pollfd p[1]; 642 struct pollfd p[1];
593#endif 643#endif
594 644
@@ -607,14 +657,6 @@ MHD_handle_connection (void *data)
607 tv.tv_usec = 0; 657 tv.tv_usec = 0;
608 tvp = &tv; 658 tvp = &tv;
609 } 659 }
610 if ( (MHD_CONNECTION_NORMAL_BODY_UNREADY == con->state) ||
611 (MHD_CONNECTION_CHUNKED_BODY_UNREADY == con->state) )
612 {
613 /* do not block (we're waiting for our callback to succeed) */
614 tv.tv_sec = 0;
615 tv.tv_usec = 0;
616 tvp = &tv;
617 }
618#if HTTPS_SUPPORT 660#if HTTPS_SUPPORT
619 if (MHD_YES == con->tls_read_ready) 661 if (MHD_YES == con->tls_read_ready)
620 { 662 {
@@ -629,10 +671,25 @@ MHD_handle_connection (void *data)
629 /* use select */ 671 /* use select */
630 FD_ZERO (&rs); 672 FD_ZERO (&rs);
631 FD_ZERO (&ws); 673 FD_ZERO (&ws);
632 FD_ZERO (&es);
633 max = 0; 674 max = 0;
634 MHD_connection_get_fdset (con, &rs, &ws, &es, &max); 675 switch (con->event_loop_info)
635 num_ready = SELECT (max + 1, &rs, &ws, &es, tvp); 676 {
677 case MHD_EVENT_LOOP_INFO_READ:
678 add_to_fd_set (con->socket_fd, &rs, &max);
679 break;
680 case MHD_EVENT_LOOP_INFO_WRITE:
681 add_to_fd_set (con->socket_fd, &ws, &max);
682 break;
683 case MHD_EVENT_LOOP_INFO_BLOCK:
684 tv.tv_sec = 0;
685 tv.tv_usec = 0;
686 tvp = &tv;
687 break;
688 case MHD_EVENT_LOOP_INFO_CLEANUP:
689 /* how did we get here!? */
690 goto exit;
691 }
692 num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp);
636 if (num_ready < 0) 693 if (num_ready < 0)
637 { 694 {
638 if (EINTR == errno) 695 if (EINTR == errno)
@@ -648,7 +705,7 @@ MHD_handle_connection (void *data)
648 /* call appropriate connection handler if necessary */ 705 /* call appropriate connection handler if necessary */
649 if ( (FD_ISSET (con->socket_fd, &rs)) 706 if ( (FD_ISSET (con->socket_fd, &rs))
650#if HTTPS_SUPPORT 707#if HTTPS_SUPPORT
651 || (MHD_YES == con->tls_read_ready) 708 || (MHD_YES == con->tls_read_ready)
652#endif 709#endif
653 ) 710 )
654 con->read_handler (con); 711 con->read_handler (con);
@@ -661,16 +718,26 @@ MHD_handle_connection (void *data)
661 else 718 else
662 { 719 {
663 /* use poll */ 720 /* use poll */
664 memset(&mp, 0, sizeof (struct MHD_Pollfd)); 721 memset (&p, 0, sizeof (p));
665 MHD_connection_get_pollfd(con, &mp); 722 p[0].fd = con->socket_fd;
666 memset(&p, 0, sizeof (p)); 723 switch (con->event_loop_info)
667 p[0].fd = mp.fd; 724 {
668 if (mp.events & MHD_POLL_ACTION_IN) 725 case MHD_EVENT_LOOP_INFO_READ:
669 p[0].events |= POLLIN; 726 p[0].events |= POLLIN;
670 if (mp.events & MHD_POLL_ACTION_OUT) 727 break;
671 p[0].events |= POLLOUT; 728 case MHD_EVENT_LOOP_INFO_WRITE:
672 if (poll (p, 729 p[0].events |= POLLOUT;
673 1, 730 break;
731 case MHD_EVENT_LOOP_INFO_BLOCK:
732 tv.tv_sec = 0;
733 tv.tv_usec = 0;
734 tvp = &tv;
735 break;
736 case MHD_EVENT_LOOP_INFO_CLEANUP:
737 /* how did we get here!? */
738 goto exit;
739 }
740 if (poll (p, 1,
674 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 741 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
675 { 742 {
676 if (EINTR == errno) 743 if (EINTR == errno)
@@ -732,15 +799,23 @@ recv_param_adapter (struct MHD_Connection *connection,
732 void *other, 799 void *other,
733 size_t i) 800 size_t i)
734{ 801{
802 ssize_t ret;
803
735 if ( (-1 == connection->socket_fd) || 804 if ( (-1 == connection->socket_fd) ||
736 (MHD_CONNECTION_CLOSED == connection->state) ) 805 (MHD_CONNECTION_CLOSED == connection->state) )
737 { 806 {
738 errno = ENOTCONN; 807 errno = ENOTCONN;
739 return -1; 808 return -1;
740 } 809 }
741 if (0 != (connection->daemon->options & MHD_USE_SSL)) 810 ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
742 return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL); 811#if EPOLL_SUPPORT
743 return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL); 812 if (ret < i)
813 {
814 /* partial read --- no longer read-ready */
815 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
816 }
817#endif
818 return ret;
744} 819}
745 820
746 821
@@ -757,12 +832,13 @@ send_param_adapter (struct MHD_Connection *connection,
757 const void *other, 832 const void *other,
758 size_t i) 833 size_t i)
759{ 834{
835 ssize_t ret;
760#if LINUX 836#if LINUX
761 int fd; 837 int fd;
762 off_t offset; 838 off_t offset;
763 off_t left; 839 off_t left;
764 ssize_t ret;
765#endif 840#endif
841
766 if ( (-1 == connection->socket_fd) || 842 if ( (-1 == connection->socket_fd) ||
767 (MHD_CONNECTION_CLOSED == connection->state) ) 843 (MHD_CONNECTION_CLOSED == connection->state) )
768 { 844 {
@@ -786,7 +862,16 @@ send_param_adapter (struct MHD_Connection *connection,
786 fd, 862 fd,
787 &offset, 863 &offset,
788 (size_t) left))) 864 (size_t) left)))
789 return ret; 865 {
866#if EPOLL_SUPPORT
867 if (ret < left)
868 {
869 /* partial write --- no longer write-ready */
870 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
871 }
872#endif
873 return ret;
874 }
790 if ( (EINTR == errno) || (EAGAIN == errno) ) 875 if ( (EINTR == errno) || (EAGAIN == errno) )
791 return 0; 876 return 0;
792 if ( (EINVAL == errno) || (EBADF == errno) ) 877 if ( (EINVAL == errno) || (EBADF == errno) )
@@ -797,7 +882,15 @@ send_param_adapter (struct MHD_Connection *connection,
797 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ 882 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
798 } 883 }
799#endif 884#endif
800 return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL); 885 ret = SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
886#if EPOLL_SUPPORT
887 if (ret < i)
888 {
889 /* partial write --- no longer write-ready */
890 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
891 }
892#endif
893 return ret;
801} 894}
802 895
803 896
@@ -890,13 +983,31 @@ MHD_add_connection (struct MHD_Daemon *daemon,
890{ 983{
891 struct MHD_Connection *connection; 984 struct MHD_Connection *connection;
892 int res_thread_create; 985 int res_thread_create;
986 unsigned int i;
893#if OSX 987#if OSX
894 static int on = 1; 988 static int on = 1;
895#endif 989#endif
990
991 if (NULL != daemon->worker_pool)
992 {
993 /* have a pool, try to find a pool with capacity; we use the
994 socket as the initial offset into the pool for load
995 balancing */
996 for (i=0;i<daemon->worker_pool_size;i++)
997 if (0 < daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size].max_connections)
998 return MHD_add_connection (&daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size],
999 client_socket,
1000 addr, addrlen);
1001 /* all pools are at their connection limit, must refuse */
1002 SHUTDOWN (client_socket, SHUT_RDWR);
1003 if (0 != CLOSE (client_socket))
1004 MHD_PANIC ("close failed\n");
1005 return MHD_NO;
1006 }
896 1007
897#ifndef WINDOWS 1008#ifndef WINDOWS
898 if ( (client_socket >= FD_SETSIZE) && 1009 if ( (client_socket >= FD_SETSIZE) &&
899 (0 == (daemon->options & MHD_USE_POLL)) ) 1010 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
900 { 1011 {
901#if HAVE_MESSAGES 1012#if HAVE_MESSAGES
902 MHD_DLOG (daemon, 1013 MHD_DLOG (daemon,
@@ -905,7 +1016,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
905 FD_SETSIZE); 1016 FD_SETSIZE);
906#endif 1017#endif
907 SHUTDOWN (client_socket, SHUT_RDWR); 1018 SHUTDOWN (client_socket, SHUT_RDWR);
908 CLOSE (client_socket); 1019 if (0 != CLOSE (client_socket))
1020 MHD_PANIC ("close failed\n");
909 return MHD_NO; 1021 return MHD_NO;
910 } 1022 }
911#endif 1023#endif
@@ -925,7 +1037,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
925 "Server reached connection limit (closing inbound connection)\n"); 1037 "Server reached connection limit (closing inbound connection)\n");
926#endif 1038#endif
927 SHUTDOWN (client_socket, SHUT_RDWR); 1039 SHUTDOWN (client_socket, SHUT_RDWR);
928 CLOSE (client_socket); 1040 if (0 != CLOSE (client_socket))
1041 MHD_PANIC ("close failed\n");
929 return MHD_NO; 1042 return MHD_NO;
930 } 1043 }
931 1044
@@ -940,9 +1053,10 @@ MHD_add_connection (struct MHD_Daemon *daemon,
940#endif 1053#endif
941#endif 1054#endif
942 SHUTDOWN (client_socket, SHUT_RDWR); 1055 SHUTDOWN (client_socket, SHUT_RDWR);
943 CLOSE (client_socket); 1056 if (0 != CLOSE (client_socket))
1057 MHD_PANIC ("close failed\n");
944 MHD_ip_limit_del (daemon, addr, addrlen); 1058 MHD_ip_limit_del (daemon, addr, addrlen);
945 return MHD_YES; 1059 return MHD_NO;
946 } 1060 }
947 1061
948#if OSX 1062#if OSX
@@ -963,13 +1077,29 @@ MHD_add_connection (struct MHD_Daemon *daemon,
963 STRERROR (errno)); 1077 STRERROR (errno));
964#endif 1078#endif
965 SHUTDOWN (client_socket, SHUT_RDWR); 1079 SHUTDOWN (client_socket, SHUT_RDWR);
966 CLOSE (client_socket); 1080 if (0 != CLOSE (client_socket))
1081 MHD_PANIC ("close failed\n");
967 MHD_ip_limit_del (daemon, addr, addrlen); 1082 MHD_ip_limit_del (daemon, addr, addrlen);
968 return MHD_NO; 1083 return MHD_NO;
969 } 1084 }
970 memset (connection, 0, sizeof (struct MHD_Connection)); 1085 memset (connection, 0, sizeof (struct MHD_Connection));
1086 connection->pool = MHD_pool_create (daemon->pool_size);
1087 if (NULL == connection->pool)
1088 {
1089#if HAVE_MESSAGES
1090 MHD_DLOG (daemon,
1091 "Error allocating memory: %s\n",
1092 STRERROR (errno));
1093#endif
1094 SHUTDOWN (client_socket, SHUT_RDWR);
1095 if (0 != CLOSE (client_socket))
1096 MHD_PANIC ("close failed\n");
1097 MHD_ip_limit_del (daemon, addr, addrlen);
1098 free (connection);
1099 return MHD_NO;
1100 }
1101
971 connection->connection_timeout = daemon->connection_timeout; 1102 connection->connection_timeout = daemon->connection_timeout;
972 connection->pool = NULL;
973 if (NULL == (connection->addr = malloc (addrlen))) 1103 if (NULL == (connection->addr = malloc (addrlen)))
974 { 1104 {
975#if HAVE_MESSAGES 1105#if HAVE_MESSAGES
@@ -978,8 +1108,10 @@ MHD_add_connection (struct MHD_Daemon *daemon,
978 STRERROR (errno)); 1108 STRERROR (errno));
979#endif 1109#endif
980 SHUTDOWN (client_socket, SHUT_RDWR); 1110 SHUTDOWN (client_socket, SHUT_RDWR);
981 CLOSE (client_socket); 1111 if (0 != CLOSE (client_socket))
1112 MHD_PANIC ("close failed\n");
982 MHD_ip_limit_del (daemon, addr, addrlen); 1113 MHD_ip_limit_del (daemon, addr, addrlen);
1114 MHD_pool_destroy (connection->pool);
983 free (connection); 1115 free (connection);
984 return MHD_NO; 1116 return MHD_NO;
985 } 1117 }
@@ -988,7 +1120,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
988 connection->socket_fd = client_socket; 1120 connection->socket_fd = client_socket;
989 connection->daemon = daemon; 1121 connection->daemon = daemon;
990 connection->last_activity = MHD_monotonic_time(); 1122 connection->last_activity = MHD_monotonic_time();
991 1123
992 /* set default connection handlers */ 1124 /* set default connection handlers */
993 MHD_set_http_callbacks_ (connection); 1125 MHD_set_http_callbacks_ (connection);
994 connection->recv_cls = &recv_param_adapter; 1126 connection->recv_cls = &recv_param_adapter;
@@ -1050,7 +1182,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1050 daemon->cred_type); 1182 daemon->cred_type);
1051#endif 1183#endif
1052 SHUTDOWN (client_socket, SHUT_RDWR); 1184 SHUTDOWN (client_socket, SHUT_RDWR);
1053 CLOSE (client_socket); 1185 if (0 != CLOSE (client_socket))
1186 MHD_PANIC ("close failed\n");
1054 MHD_ip_limit_del (daemon, addr, addrlen); 1187 MHD_ip_limit_del (daemon, addr, addrlen);
1055 free (connection->addr); 1188 free (connection->addr);
1056 free (connection); 1189 free (connection);
@@ -1065,16 +1198,22 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1065 (gnutls_push_func) &send_param_adapter); 1198 (gnutls_push_func) &send_param_adapter);
1066 1199
1067 if (daemon->https_mem_trust) 1200 if (daemon->https_mem_trust)
1068 gnutls_certificate_server_set_request(connection->tls_session, GNUTLS_CERT_REQUEST); 1201 gnutls_certificate_server_set_request (connection->tls_session,
1202 GNUTLS_CERT_REQUEST);
1069 } 1203 }
1070#endif 1204#endif
1071 1205
1072 if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) 1206 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1207 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1073 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1208 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1209 XDLL_insert (daemon->normal_timeout_head,
1210 daemon->normal_timeout_tail,
1211 connection);
1074 DLL_insert (daemon->connections_head, 1212 DLL_insert (daemon->connections_head,
1075 daemon->connections_tail, 1213 daemon->connections_tail,
1076 connection); 1214 connection);
1077 if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) 1215 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1216 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1078 MHD_PANIC ("Failed to release cleanup mutex\n"); 1217 MHD_PANIC ("Failed to release cleanup mutex\n");
1079 1218
1080 /* attempt to create handler thread */ 1219 /* attempt to create handler thread */
@@ -1088,27 +1227,58 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1088 MHD_DLOG (daemon, "Failed to create a thread: %s\n", 1227 MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1089 STRERROR (res_thread_create)); 1228 STRERROR (res_thread_create));
1090#endif 1229#endif
1091 SHUTDOWN (client_socket, SHUT_RDWR); 1230 goto cleanup;
1092 CLOSE (client_socket);
1093 MHD_ip_limit_del (daemon, addr, addrlen);
1094 if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex))
1095 {
1096 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1097 }
1098 DLL_remove (daemon->connections_head,
1099 daemon->connections_tail,
1100 connection);
1101 if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
1102 {
1103 MHD_PANIC ("Failed to release cleanup mutex\n");
1104 }
1105 free (connection->addr);
1106 free (connection);
1107 return MHD_NO;
1108 } 1231 }
1109 } 1232 }
1110 daemon->max_connections--; 1233#if EPOLL_SUPPORT
1234 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1235 {
1236 struct epoll_event event;
1237
1238 event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1239 event.data.ptr = connection;
1240 if (0 != epoll_ctl (daemon->epoll_fd,
1241 EPOLL_CTL_ADD,
1242 client_socket,
1243 &event))
1244 {
1245#if HAVE_MESSAGES
1246 if (0 != (daemon->options & MHD_USE_DEBUG))
1247 MHD_DLOG (daemon,
1248 "Call to epoll_ctl failed: %s\n",
1249 STRERROR (errno));
1250#endif
1251 goto cleanup;
1252 }
1253 daemon->listen_socket_in_epoll = MHD_YES;
1254
1255 }
1256#endif
1257 daemon->max_connections--;
1111 return MHD_YES; 1258 return MHD_YES;
1259#if HTTPS_SUPPORT || EPOLL_SUPPORT
1260 cleanup:
1261 SHUTDOWN (client_socket, SHUT_RDWR);
1262 if (0 != CLOSE (client_socket))
1263 MHD_PANIC ("close failed\n");
1264 MHD_ip_limit_del (daemon, addr, addrlen);
1265 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1266 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1267 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1268 DLL_remove (daemon->connections_head,
1269 daemon->connections_tail,
1270 connection);
1271 XDLL_remove (daemon->normal_timeout_head,
1272 daemon->normal_timeout_tail,
1273 connection);
1274 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1275 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1276 MHD_PANIC ("Failed to release cleanup mutex\n");
1277 MHD_pool_destroy (connection->pool);
1278 free (connection->addr);
1279 free (connection);
1280 return MHD_NO;
1281#endif
1112} 1282}
1113 1283
1114 1284
@@ -1118,7 +1288,11 @@ MHD_add_connection (struct MHD_Daemon *daemon,
1118 * accept policy callback. 1288 * accept policy callback.
1119 * 1289 *
1120 * @param daemon handle with the listen socket 1290 * @param daemon handle with the listen socket
1121 * @return MHD_YES on success 1291 * @return MHD_YES on success (connections denied by policy or due
1292 * to 'out of memory' and similar errors) are still considered
1293 * successful as far as MHD_accept_connection is concerned);
1294 * a return code of MHD_NO only refers to the actual
1295 * 'accept' system call.
1122 */ 1296 */
1123static int 1297static int
1124MHD_accept_connection (struct MHD_Daemon *daemon) 1298MHD_accept_connection (struct MHD_Daemon *daemon)
@@ -1143,14 +1317,9 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1143 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC); 1317 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC);
1144 need_fcntl = MHD_NO; 1318 need_fcntl = MHD_NO;
1145#else 1319#else
1146 s = -1; 1320 s = ACCEPT (fd, addr, &addrlen);
1147 need_fcntl = MHD_YES; 1321 need_fcntl = MHD_YES;
1148#endif 1322#endif
1149 if (-1 == s)
1150 {
1151 s = ACCEPT (fd, addr, &addrlen);
1152 need_fcntl = MHD_YES;
1153 }
1154 if ((-1 == s) || (addrlen <= 0)) 1323 if ((-1 == s) || (addrlen <= 0))
1155 { 1324 {
1156#if HAVE_MESSAGES 1325#if HAVE_MESSAGES
@@ -1163,11 +1332,13 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1163 if (-1 != s) 1332 if (-1 != s)
1164 { 1333 {
1165 SHUTDOWN (s, SHUT_RDWR); 1334 SHUTDOWN (s, SHUT_RDWR);
1166 CLOSE (s); 1335 if (0 != CLOSE (s))
1336 MHD_PANIC ("close failed\n");
1167 /* just in case */ 1337 /* just in case */
1168 } 1338 }
1169 return MHD_NO; 1339 return MHD_NO;
1170 } 1340 }
1341#if !HAVE_ACCEPT4
1171 if (MHD_YES == need_fcntl) 1342 if (MHD_YES == need_fcntl)
1172 { 1343 {
1173 /* make socket non-inheritable */ 1344 /* make socket non-inheritable */
@@ -1198,13 +1369,15 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1198 } 1369 }
1199#endif 1370#endif
1200 } 1371 }
1372#endif
1201#if HAVE_MESSAGES 1373#if HAVE_MESSAGES
1202#if DEBUG_CONNECT 1374#if DEBUG_CONNECT
1203 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); 1375 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
1204#endif 1376#endif
1205#endif 1377#endif
1206 return MHD_add_connection (daemon, s, 1378 (void) MHD_add_connection (daemon, s,
1207 addr, addrlen); 1379 addr, addrlen);
1380 return MHD_YES;
1208} 1381}
1209 1382
1210 1383
@@ -1222,10 +1395,9 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1222 void *unused; 1395 void *unused;
1223 int rc; 1396 int rc;
1224 1397
1225 if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) 1398 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1226 { 1399 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1227 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1400 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1228 }
1229 while (NULL != (pos = daemon->cleanup_head)) 1401 while (NULL != (pos = daemon->cleanup_head))
1230 { 1402 {
1231 DLL_remove (daemon->cleanup_head, 1403 DLL_remove (daemon->cleanup_head,
@@ -1245,22 +1417,39 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1245 gnutls_deinit (pos->tls_session); 1417 gnutls_deinit (pos->tls_session);
1246#endif 1418#endif
1247 MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len); 1419 MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len);
1420#if EPOLL_SUPPORT
1421 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
1422 (-1 != daemon->epoll_fd) )
1423 {
1424 /* epoll documentation suggests that closing a FD
1425 automatically removes it from the epoll set; however,
1426 this is not true as if we fail to do manually remove it,
1427 we are still seeing an event for this fd in epoll,
1428 causing grief (use-after-free...) --- at least on my
1429 system. */
1430 if (0 != epoll_ctl (daemon->epoll_fd,
1431 EPOLL_CTL_DEL,
1432 pos->socket_fd,
1433 NULL))
1434 MHD_PANIC ("Failed to remove FD from epoll set\n");
1435 }
1436#endif
1248 if (NULL != pos->response) 1437 if (NULL != pos->response)
1249 { 1438 {
1250 MHD_destroy_response (pos->response); 1439 MHD_destroy_response (pos->response);
1251 pos->response = NULL; 1440 pos->response = NULL;
1252 } 1441 }
1253 if (-1 != pos->socket_fd) 1442 if ( (-1 != pos->socket_fd) &&
1254 CLOSE (pos->socket_fd); 1443 (0 != CLOSE (pos->socket_fd)) )
1444 MHD_PANIC ("close failed\n");
1255 if (NULL != pos->addr) 1445 if (NULL != pos->addr)
1256 free (pos->addr); 1446 free (pos->addr);
1257 free (pos); 1447 free (pos);
1258 daemon->max_connections++; 1448 daemon->max_connections++;
1259 } 1449 }
1260 if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) 1450 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1261 { 1451 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1262 MHD_PANIC ("Failed to release cleanup mutex\n"); 1452 MHD_PANIC ("Failed to release cleanup mutex\n");
1263 }
1264} 1453}
1265 1454
1266 1455
@@ -1292,17 +1481,20 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
1292#endif 1481#endif
1293 return MHD_NO; 1482 return MHD_NO;
1294 } 1483 }
1295 have_timeout = MHD_NO; 1484
1296 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1297 {
1298#if HTTPS_SUPPORT 1485#if HTTPS_SUPPORT
1299 if (MHD_YES == pos->tls_read_ready) 1486 if (0 != daemon->num_tls_read_ready)
1300 { 1487 {
1301 earliest_deadline = 0; 1488 /* if there is any TLS connection with data ready for
1302 have_timeout = MHD_YES; 1489 reading, we must not block in the event loop */
1303 break; 1490 *timeout = 0;
1304 } 1491 return MHD_YES;
1492 }
1305#endif 1493#endif
1494
1495 have_timeout = MHD_NO;
1496 for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
1497 {
1306 if (0 != pos->connection_timeout) 1498 if (0 != pos->connection_timeout)
1307 { 1499 {
1308 if ( (! have_timeout) || 1500 if ( (! have_timeout) ||
@@ -1316,6 +1508,22 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
1316 have_timeout = MHD_YES; 1508 have_timeout = MHD_YES;
1317 } 1509 }
1318 } 1510 }
1511 /* normal timeouts are sorted, so we only need to look at the 'head' */
1512 pos = daemon->normal_timeout_head;
1513 if ( (NULL != pos) &&
1514 (0 != pos->connection_timeout) )
1515 {
1516 if ( (! have_timeout) ||
1517 (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1518 earliest_deadline = pos->last_activity + pos->connection_timeout;
1519#if HTTPS_SUPPORT
1520 if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1521 (0 != gnutls_record_check_pending (pos->tls_session)) )
1522 earliest_deadline = 0;
1523#endif
1524 have_timeout = MHD_YES;
1525 }
1526
1319 if (MHD_NO == have_timeout) 1527 if (MHD_NO == have_timeout)
1320 return MHD_NO; 1528 return MHD_NO;
1321 now = MHD_monotonic_time(); 1529 now = MHD_monotonic_time();
@@ -1356,10 +1564,23 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
1356 struct MHD_Connection *pos; 1564 struct MHD_Connection *pos;
1357 struct MHD_Connection *next; 1565 struct MHD_Connection *next;
1358 1566
1567#if EPOLL_SUPPORT
1568 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1569 {
1570 /* we're in epoll mode, the epoll FD stands for
1571 the entire event set! */
1572 if (daemon->epoll_fd >= FD_SETSIZE)
1573 return MHD_NO; /* poll fd too big, fail hard */
1574 if (FD_ISSET (daemon->epoll_fd, read_fd_set))
1575 return MHD_run (daemon);
1576 return MHD_YES;
1577 }
1578#endif
1579
1359 /* select connection thread handling type */ 1580 /* select connection thread handling type */
1360 if ( (-1 != (ds = daemon->socket_fd)) && 1581 if ( (-1 != (ds = daemon->socket_fd)) &&
1361 (FD_ISSET (ds, read_fd_set)) ) 1582 (FD_ISSET (ds, read_fd_set)) )
1362 MHD_accept_connection (daemon); 1583 (void) MHD_accept_connection (daemon);
1363 /* drain signaling pipe to avoid spinning select */ 1584 /* drain signaling pipe to avoid spinning select */
1364 if ( (-1 != daemon->wpipe[0]) && 1585 if ( (-1 != daemon->wpipe[0]) &&
1365 (FD_ISSET (daemon->wpipe[0], read_fd_set)) ) 1586 (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
@@ -1373,18 +1594,30 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
1373 { 1594 {
1374 next = pos->next; 1595 next = pos->next;
1375 ds = pos->socket_fd; 1596 ds = pos->socket_fd;
1376 if (ds != -1) 1597 if (-1 == ds)
1377 { 1598 continue;
1378 if ( (FD_ISSET (ds, read_fd_set)) 1599 switch (pos->event_loop_info)
1600 {
1601 case MHD_EVENT_LOOP_INFO_READ:
1602 if ( (FD_ISSET (ds, read_fd_set))
1379#if HTTPS_SUPPORT 1603#if HTTPS_SUPPORT
1380 || (MHD_YES == pos->tls_read_ready) 1604 || (MHD_YES == pos->tls_read_ready)
1381#endif 1605#endif
1382 ) 1606 )
1383 pos->read_handler (pos); 1607 pos->read_handler (pos);
1384 if (FD_ISSET (ds, write_fd_set)) 1608 break;
1385 pos->write_handler (pos); 1609 case MHD_EVENT_LOOP_INFO_WRITE:
1386 pos->idle_handler (pos); 1610 if (FD_ISSET (ds, write_fd_set))
1387 } 1611 pos->write_handler (pos);
1612 break;
1613 case MHD_EVENT_LOOP_INFO_BLOCK:
1614 /* only idle handler */
1615 break;
1616 case MHD_EVENT_LOOP_INFO_CLEANUP:
1617 /* should never happen */
1618 break;
1619 }
1620 pos->idle_handler (pos);
1388 } 1621 }
1389 } 1622 }
1390 return MHD_YES; 1623 return MHD_YES;
@@ -1502,11 +1735,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1502 /* count number of connections and thus determine poll set size */ 1735 /* count number of connections and thus determine poll set size */
1503 num_connections = 0; 1736 num_connections = 0;
1504 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 1737 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1505 num_connections++; 1738 if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
1506 1739 (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) )
1740 num_connections++;
1507 { 1741 {
1508 struct pollfd p[2 + num_connections]; 1742 struct pollfd p[2 + num_connections];
1509 struct MHD_Pollfd mp;
1510 MHD_UNSIGNED_LONG_LONG ltimeout; 1743 MHD_UNSIGNED_LONG_LONG ltimeout;
1511 unsigned int i; 1744 unsigned int i;
1512 int timeout; 1745 int timeout;
@@ -1544,13 +1777,22 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1544 i = 0; 1777 i = 0;
1545 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 1778 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1546 { 1779 {
1547 memset(&mp, 0, sizeof (struct MHD_Pollfd)); 1780 p[poll_server+i].fd = pos->socket_fd;
1548 MHD_connection_get_pollfd (pos, &mp); 1781 switch (pos->event_loop_info)
1549 p[poll_server+i].fd = mp.fd; 1782 {
1550 if (mp.events & MHD_POLL_ACTION_IN) 1783 case MHD_EVENT_LOOP_INFO_READ:
1551 p[poll_server+i].events |= POLLIN; 1784 p[poll_server+i].events |= POLLIN;
1552 if (mp.events & MHD_POLL_ACTION_OUT) 1785 break;
1553 p[poll_server+i].events |= POLLOUT; 1786 case MHD_EVENT_LOOP_INFO_WRITE:
1787 p[poll_server+i].events |= POLLOUT;
1788 break;
1789 case MHD_EVENT_LOOP_INFO_BLOCK:
1790 /* not in poll */
1791 break;
1792 case MHD_EVENT_LOOP_INFO_CLEANUP:
1793 /* should never happen */
1794 break;
1795 }
1554 i++; 1796 i++;
1555 } 1797 }
1556 if (0 == poll_server + num_connections) 1798 if (0 == poll_server + num_connections)
@@ -1574,24 +1816,44 @@ MHD_poll_all (struct MHD_Daemon *daemon,
1574 while (NULL != (pos = next)) 1816 while (NULL != (pos = next))
1575 { 1817 {
1576 next = pos->next; 1818 next = pos->next;
1577 /* first, sanity checks */ 1819 switch (pos->event_loop_info)
1578 if (i >= num_connections) 1820 {
1579 break; /* connection list changed somehow, retry later ... */ 1821 case MHD_EVENT_LOOP_INFO_READ:
1580 MHD_connection_get_pollfd (pos, &mp); 1822 /* first, sanity checks */
1581 if (p[poll_server+i].fd != mp.fd) 1823 if (i >= num_connections)
1582 break; /* fd mismatch, something else happened, retry later ... */ 1824 break; /* connection list changed somehow, retry later ... */
1583 1825 if (p[poll_server+i].fd != pos->socket_fd)
1584 /* normal handling */ 1826 break; /* fd mismatch, something else happened, retry later ... */
1585 if (0 != (p[poll_server+i].revents & POLLIN)) 1827 /* normal handling */
1586 pos->read_handler (pos); 1828 if (0 != (p[poll_server+i].revents & POLLIN))
1587 if (0 != (p[poll_server+i].revents & POLLOUT)) 1829 pos->read_handler (pos);
1588 pos->write_handler (pos); 1830 pos->idle_handler (pos);
1589 pos->idle_handler (pos); 1831 i++;
1590 i++; 1832 break;
1833 case MHD_EVENT_LOOP_INFO_WRITE:
1834 /* first, sanity checks */
1835 if (i >= num_connections)
1836 break; /* connection list changed somehow, retry later ... */
1837 if (p[poll_server+i].fd != pos->socket_fd)
1838 break; /* fd mismatch, something else happened, retry later ... */
1839 /* normal handling */
1840 if (0 != (p[poll_server+i].revents & POLLOUT))
1841 pos->write_handler (pos);
1842 pos->idle_handler (pos);
1843 i++;
1844 break;
1845 case MHD_EVENT_LOOP_INFO_BLOCK:
1846 pos->idle_handler (pos);
1847 break;
1848 case MHD_EVENT_LOOP_INFO_CLEANUP:
1849 /* should never happen */
1850 break;
1851 }
1591 } 1852 }
1853 /* handle 'listen' FD */
1592 if ( (-1 != poll_listen) && 1854 if ( (-1 != poll_listen) &&
1593 (0 != (p[poll_listen].revents & POLLIN)) ) 1855 (0 != (p[poll_listen].revents & POLLIN)) )
1594 MHD_accept_connection (daemon); 1856 (void) MHD_accept_connection (daemon);
1595 } 1857 }
1596 return MHD_YES; 1858 return MHD_YES;
1597} 1859}
@@ -1651,7 +1913,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
1651 return MHD_NO; 1913 return MHD_NO;
1652 if ( (-1 != poll_listen) && 1914 if ( (-1 != poll_listen) &&
1653 (0 != (p[poll_listen].revents & POLLIN)) ) 1915 (0 != (p[poll_listen].revents & POLLIN)) )
1654 MHD_accept_connection (daemon); 1916 (void) MHD_accept_connection (daemon);
1655 return MHD_YES; 1917 return MHD_YES;
1656} 1918}
1657#endif 1919#endif
@@ -1681,6 +1943,204 @@ MHD_poll (struct MHD_Daemon *daemon,
1681} 1943}
1682 1944
1683 1945
1946#if EPOLL_SUPPORT
1947
1948/**
1949 * How many events to we process at most per epoll call? Trade-off
1950 * between required stack-size and number of system calls we have to
1951 * make; 128 should be way enough to avoid more than one system call
1952 * for most scenarios, and still be moderate in stack size
1953 * consumption. Embedded systems might want to choose a smaller value
1954 * --- but why use 'epoll' on such a system in the first place?
1955 */
1956#define MAX_EVENTS 128
1957
1958
1959/**
1960 * Do 'epoll'-based processing (this function is allowed to
1961 * block).
1962 *
1963 * @param daemon daemon to run poll loop for
1964 * @param may_block YES if blocking, NO if non-blocking
1965 * @return MHD_NO on serious errors, MHD_YES on success
1966 */
1967static int
1968MHD_epoll (struct MHD_Daemon *daemon,
1969 int may_block)
1970{
1971 struct MHD_Connection *pos;
1972 struct MHD_Connection *next;
1973 struct epoll_event events[MAX_EVENTS];
1974 struct epoll_event event;
1975 int timeout_ms;
1976 MHD_UNSIGNED_LONG_LONG timeout_ll;
1977 int num_events;
1978 unsigned int i;
1979
1980 if (-1 == daemon->epoll_fd)
1981 return MHD_NO; /* we're down! */
1982 if (MHD_YES == daemon->shutdown)
1983 return MHD_NO;
1984 if ( (-1 != daemon->socket_fd) &&
1985 (0 != daemon->max_connections) &&
1986 (MHD_NO == daemon->listen_socket_in_epoll) )
1987 {
1988 event.events = EPOLLIN;
1989 event.data.ptr = daemon;
1990 if (0 != epoll_ctl (daemon->epoll_fd,
1991 EPOLL_CTL_ADD,
1992 daemon->socket_fd,
1993 &event))
1994 {
1995#if HAVE_MESSAGES
1996 if (0 != (daemon->options & MHD_USE_DEBUG))
1997 MHD_DLOG (daemon,
1998 "Call to epoll_ctl failed: %s\n",
1999 STRERROR (errno));
2000#endif
2001 return MHD_NO;
2002 }
2003 daemon->listen_socket_in_epoll = MHD_YES;
2004 }
2005 if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2006 (0 == daemon->max_connections) )
2007 {
2008 /* we're at the connection limit, disable listen socket
2009 for event loop for now */
2010 if (0 != epoll_ctl (daemon->epoll_fd,
2011 EPOLL_CTL_DEL,
2012 daemon->socket_fd,
2013 NULL))
2014 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2015 daemon->listen_socket_in_epoll = MHD_NO;
2016 }
2017 if (MHD_YES == may_block)
2018 {
2019 if (MHD_YES == MHD_get_timeout (daemon,
2020 &timeout_ll))
2021 {
2022 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2023 timeout_ms = INT_MAX;
2024 else
2025 timeout_ms = (int) timeout_ll;
2026 }
2027 else
2028 timeout_ms = -1;
2029 }
2030 else
2031 timeout_ms = 0;
2032
2033 /* drain 'epoll' event queue; need to iterate as we get at most
2034 MAX_EVENTS in one system call here; in practice this should
2035 pretty much mean only one round, but better an extra loop here
2036 than unfair behavior... */
2037 num_events = MAX_EVENTS;
2038 while (MAX_EVENTS == num_events)
2039 {
2040 /* update event masks */
2041 num_events = epoll_wait (daemon->epoll_fd,
2042 events, MAX_EVENTS, timeout_ms);
2043 if (-1 == num_events)
2044 {
2045 if (EINTR == errno)
2046 return MHD_YES;
2047#if HAVE_MESSAGES
2048 if (0 != (daemon->options & MHD_USE_DEBUG))
2049 MHD_DLOG (daemon,
2050 "Call to epoll_wait failed: %s\n",
2051 STRERROR (errno));
2052#endif
2053 return MHD_NO;
2054 }
2055 for (i=0;i<num_events;i++)
2056 {
2057 if (NULL == events[i].data.ptr)
2058 continue; /* shutdown signal! */
2059 if (daemon != events[i].data.ptr)
2060 {
2061 /* this is an event relating to a 'normal' connection,
2062 remember the event and if appropriate mark the
2063 connection as 'eready'. */
2064 pos = events[i].data.ptr;
2065 if (0 != (events[i].events & EPOLLIN))
2066 {
2067 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2068 if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
2069 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2070 {
2071 EDLL_insert (daemon->eready_head,
2072 daemon->eready_tail,
2073 pos);
2074 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2075 }
2076 }
2077 if (0 != (events[i].events & EPOLLOUT))
2078 {
2079 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2080 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2081 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2082 {
2083 EDLL_insert (daemon->eready_head,
2084 daemon->eready_tail,
2085 pos);
2086 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2087 }
2088 }
2089 }
2090 else /* must be listen socket */
2091 {
2092 /* run 'accept' until it fails or we are not allowed to take
2093 on more connections */
2094 while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2095 (0 != daemon->max_connections) ) ;
2096 }
2097 }
2098 }
2099
2100 /* process events for connections */
2101 while (NULL != (pos = daemon->eready_tail))
2102 {
2103 EDLL_remove (daemon->eready_head,
2104 daemon->eready_tail,
2105 pos);
2106 pos->epoll_state -= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2107 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info)
2108 pos->read_handler (pos);
2109 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info)
2110 pos->write_handler (pos);
2111 pos->idle_handler (pos);
2112 }
2113 /* Finally, handle timed-out connections; we need to do this here
2114 as the epoll mechanism won't call the 'idle_handler' on everything,
2115 as the other event loops do. As timeouts do not get an explicit
2116 event, we need to find those connections that might have timed out
2117 here.
2118
2119 Connections with custom timeouts must all be looked at, as we
2120 do not bother to sort that (presumably very short) list. */
2121 next = daemon->manual_timeout_head;
2122 while (NULL != (pos = next))
2123 {
2124 next = pos->nextX;
2125 pos->idle_handler (pos);
2126 }
2127 /* Connections with the default timeout are sorted by prepending
2128 them to the head of the list whenever we touch the connection;
2129 thus it sufficies to iterate from the tail until the first
2130 connection is NOT timed out */
2131 next = daemon->normal_timeout_tail;
2132 while (NULL != (pos = next))
2133 {
2134 next = pos->prevX;
2135 pos->idle_handler (pos);
2136 if (MHD_CONNECTION_CLOSED != pos->state)
2137 break; /* sorted by timeout, no need to visit the rest! */
2138 }
2139 return MHD_YES;
2140}
2141#endif
2142
2143
1684/** 2144/**
1685 * Run webserver operations (without blocking unless 2145 * Run webserver operations (without blocking unless
1686 * in client callbacks). This method should be called 2146 * in client callbacks). This method should be called
@@ -1702,10 +2162,14 @@ MHD_run (struct MHD_Daemon *daemon)
1702 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 2162 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1703 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) 2163 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
1704 return MHD_NO; 2164 return MHD_NO;
1705 if (0 == (daemon->options & MHD_USE_POLL)) 2165 if (0 != (daemon->options & MHD_USE_POLL))
1706 MHD_select (daemon, MHD_NO);
1707 else
1708 MHD_poll (daemon, MHD_NO); 2166 MHD_poll (daemon, MHD_NO);
2167#if EPOLL_SUPPORT
2168 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2169 MHD_epoll (daemon, MHD_NO);
2170#endif
2171 else
2172 MHD_select (daemon, MHD_NO);
1709 MHD_cleanup_connections (daemon); 2173 MHD_cleanup_connections (daemon);
1710 return MHD_YES; 2174 return MHD_YES;
1711} 2175}
@@ -1725,10 +2189,14 @@ MHD_select_thread (void *cls)
1725 2189
1726 while (MHD_YES != daemon->shutdown) 2190 while (MHD_YES != daemon->shutdown)
1727 { 2191 {
1728 if (0 == (daemon->options & MHD_USE_POLL)) 2192 if (0 != (daemon->options & MHD_USE_POLL))
1729 MHD_select (daemon, MHD_YES); 2193 MHD_poll (daemon, MHD_YES);
2194#if EPOLL_SUPPORT
2195 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2196 MHD_epoll (daemon, MHD_YES);
2197#endif
1730 else 2198 else
1731 MHD_poll (daemon, MHD_YES); 2199 MHD_select (daemon, MHD_YES);
1732 MHD_cleanup_connections (daemon); 2200 MHD_cleanup_connections (daemon);
1733 } 2201 }
1734 return NULL; 2202 return NULL;
@@ -1784,10 +2252,50 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
1784 int ret; 2252 int ret;
1785 2253
1786 ret = daemon->socket_fd; 2254 ret = daemon->socket_fd;
2255 if (-1 == ret)
2256 return -1;
2257 if ( (-1 == daemon->wpipe[1]) &&
2258 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2259 {
2260#if HAVE_MESSAGES
2261 MHD_DLOG (daemon,
2262 "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
2263#endif
2264 return -1;
2265 }
2266
1787 if (NULL != daemon->worker_pool) 2267 if (NULL != daemon->worker_pool)
1788 for (i = 0; i < daemon->worker_pool_size; i++) 2268 for (i = 0; i < daemon->worker_pool_size; i++)
1789 daemon->worker_pool[i].socket_fd = -1; 2269 {
2270 daemon->worker_pool[i].socket_fd = -1;
2271#if EPOLL_SUPPORT
2272 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2273 (-1 != daemon->worker_pool[i].epoll_fd) &&
2274 (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
2275 {
2276 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
2277 EPOLL_CTL_DEL,
2278 ret,
2279 NULL))
2280 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2281 daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
2282 }
2283#endif
2284 }
1790 daemon->socket_fd = -1; 2285 daemon->socket_fd = -1;
2286#if EPOLL_SUPPORT
2287 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2288 (-1 != daemon->epoll_fd) &&
2289 (MHD_YES == daemon->listen_socket_in_epoll) )
2290 {
2291 if (0 != epoll_ctl (daemon->epoll_fd,
2292 EPOLL_CTL_DEL,
2293 ret,
2294 NULL))
2295 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2296 daemon->listen_socket_in_epoll = MHD_NO;
2297 }
2298#endif
1791 return ret; 2299 return ret;
1792} 2300}
1793 2301
@@ -2157,6 +2665,54 @@ create_socket (int domain, int type, int protocol)
2157} 2665}
2158 2666
2159 2667
2668#if EPOLL_SUPPORT
2669/**
2670 * Setup epoll FD for the daemon and initialize it to listen
2671 * on the listen FD.
2672 *
2673 * @param daemon daemon to initialize for epoll
2674 * @return MHD_YES on success, MHD_NO on failure
2675 */
2676static int
2677setup_epoll_to_listen (struct MHD_Daemon *daemon)
2678{
2679 struct epoll_event event;
2680
2681 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
2682 if (-1 == daemon->epoll_fd)
2683 {
2684#if HAVE_MESSAGES
2685 if (0 != (daemon->options & MHD_USE_DEBUG))
2686 MHD_DLOG (daemon,
2687 "Call to epoll_create1 failed: %s\n",
2688 STRERROR (errno));
2689#endif
2690 return MHD_NO;
2691 }
2692 if (-1 == daemon->socket_fd)
2693 return MHD_YES; /* non-listening daemon */
2694 event.events = EPOLLIN;
2695 event.data.ptr = daemon;
2696 if (0 != epoll_ctl (daemon->epoll_fd,
2697 EPOLL_CTL_ADD,
2698 daemon->socket_fd,
2699 &event))
2700 {
2701#if HAVE_MESSAGES
2702 if (0 != (daemon->options & MHD_USE_DEBUG))
2703 MHD_DLOG (daemon,
2704 "Call to epoll_ctl failed: %s\n",
2705 STRERROR (errno));
2706#endif
2707 return MHD_NO;
2708 }
2709 daemon->listen_socket_in_epoll = MHD_YES;
2710 return MHD_YES;
2711}
2712#endif
2713
2714
2715
2160/** 2716/**
2161 * Start a webserver on the given port. 2717 * Start a webserver on the given port.
2162 * 2718 *
@@ -2209,6 +2765,9 @@ MHD_start_daemon_va (unsigned int flags,
2209 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) 2765 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
2210 return NULL; 2766 return NULL;
2211 memset (daemon, 0, sizeof (struct MHD_Daemon)); 2767 memset (daemon, 0, sizeof (struct MHD_Daemon));
2768#if EPOLL_SUPPORT
2769 daemon->epoll_fd = -1;
2770#endif
2212 /* try to open listen socket */ 2771 /* try to open listen socket */
2213#if HTTPS_SUPPORT 2772#if HTTPS_SUPPORT
2214 if (0 != (flags & MHD_USE_SSL)) 2773 if (0 != (flags & MHD_USE_SSL))
@@ -2236,10 +2795,12 @@ MHD_start_daemon_va (unsigned int flags,
2236 daemon->custom_error_log_cls = stderr; 2795 daemon->custom_error_log_cls = stderr;
2237#endif 2796#endif
2238#ifdef HAVE_LISTEN_SHUTDOWN 2797#ifdef HAVE_LISTEN_SHUTDOWN
2239 use_pipe = (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET)); 2798 use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
2240#else 2799#else
2241 use_pipe = 1; /* yes, must use pipe to signal shutdown */ 2800 use_pipe = 1; /* yes, must use pipe to signal shutdown */
2242#endif 2801#endif
2802 if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
2803 use_pipe = 0; /* useless if we are using 'external' select */
2243 if ( (use_pipe) && 2804 if ( (use_pipe) &&
2244 (0 != PIPE (daemon->wpipe)) ) 2805 (0 != PIPE (daemon->wpipe)) )
2245 { 2806 {
@@ -2259,8 +2820,10 @@ MHD_start_daemon_va (unsigned int flags,
2259 MHD_DLOG (daemon, 2820 MHD_DLOG (daemon,
2260 "file descriptor for control pipe exceeds maximum value\n"); 2821 "file descriptor for control pipe exceeds maximum value\n");
2261#endif 2822#endif
2262 CLOSE (daemon->wpipe[0]); 2823 if (0 != CLOSE (daemon->wpipe[0]))
2263 CLOSE (daemon->wpipe[1]); 2824 MHD_PANIC ("close failed\n");
2825 if (0 != CLOSE (daemon->wpipe[1]))
2826 MHD_PANIC ("close failed\n");
2264 free (daemon); 2827 free (daemon);
2265 return NULL; 2828 return NULL;
2266 } 2829 }
@@ -2291,7 +2854,7 @@ MHD_start_daemon_va (unsigned int flags,
2291#ifdef DAUTH_SUPPORT 2854#ifdef DAUTH_SUPPORT
2292 if (daemon->nonce_nc_size > 0) 2855 if (daemon->nonce_nc_size > 0)
2293 { 2856 {
2294 if ( ( (size_t) (daemon->nonce_nc_size * sizeof(struct MHD_NonceNc))) / 2857 if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
2295 sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) 2858 sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
2296 { 2859 {
2297#if HAVE_MESSAGES 2860#if HAVE_MESSAGES
@@ -2305,7 +2868,7 @@ MHD_start_daemon_va (unsigned int flags,
2305 free (daemon); 2868 free (daemon);
2306 return NULL; 2869 return NULL;
2307 } 2870 }
2308 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof(struct MHD_NonceNc)); 2871 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
2309 if (NULL == daemon->nnc) 2872 if (NULL == daemon->nnc)
2310 { 2873 {
2311#if HAVE_MESSAGES 2874#if HAVE_MESSAGES
@@ -2359,6 +2922,32 @@ MHD_start_daemon_va (unsigned int flags,
2359 goto free_and_fail; 2922 goto free_and_fail;
2360 } 2923 }
2361#endif 2924#endif
2925#if EPOLL_SUPPORT
2926 if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
2927 (0 == daemon->worker_pool_size) &&
2928 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
2929 {
2930 if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
2931 {
2932#if HAVE_MESSAGES
2933 MHD_DLOG (daemon,
2934 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
2935#endif
2936 goto free_and_fail;
2937 }
2938 if (MHD_YES != setup_epoll_to_listen (daemon))
2939 goto free_and_fail;
2940 }
2941#else
2942 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
2943 {
2944#if HAVE_MESSAGES
2945 MHD_DLOG (daemon,
2946 "epoll is not supported on this platform by this build.\n");
2947#endif
2948 goto free_and_fail;
2949 }
2950#endif
2362 if ( (-1 == daemon->socket_fd) && 2951 if ( (-1 == daemon->socket_fd) &&
2363 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) 2952 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
2364 { 2953 {
@@ -2377,10 +2966,11 @@ MHD_start_daemon_va (unsigned int flags,
2377#endif 2966#endif
2378 goto free_and_fail; 2967 goto free_and_fail;
2379 } 2968 }
2380 if ((SETSOCKOPT (socket_fd, 2969 if ( (0 > SETSOCKOPT (socket_fd,
2381 SOL_SOCKET, 2970 SOL_SOCKET,
2382 SO_REUSEADDR, 2971 SO_REUSEADDR,
2383 &on, sizeof (on)) < 0) && ((flags & MHD_USE_DEBUG) != 0)) 2972 &on, sizeof (on))) &&
2973 (0 != (flags & MHD_USE_DEBUG)) )
2384 { 2974 {
2385#if HAVE_MESSAGES 2975#if HAVE_MESSAGES
2386 MHD_DLOG (daemon, 2976 MHD_DLOG (daemon,
@@ -2423,25 +3013,31 @@ MHD_start_daemon_va (unsigned int flags,
2423 } 3013 }
2424 daemon->socket_fd = socket_fd; 3014 daemon->socket_fd = socket_fd;
2425 3015
2426 if (0 != (flags & MHD_USE_IPv6)) 3016 if ( (0 != (flags & MHD_USE_IPv6)) &&
3017 (0 == (flags & MHD_USE_DUAL_STACK)) )
2427 { 3018 {
2428#ifdef IPPROTO_IPV6 3019#ifdef IPPROTO_IPV6
2429#ifdef IPV6_V6ONLY 3020#ifdef IPV6_V6ONLY
2430 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" 3021 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
2431 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); 3022 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
2432 and may also be missing on older POSIX systems; good luck if you have any of those, 3023 and may also be missing on older POSIX systems; good luck if you have any of those,
2433 your IPv6 socket may then also bind against IPv4... */ 3024 your IPv6 socket may then also bind against IPv4 anyway... */
2434#ifndef WINDOWS 3025#ifndef WINDOWS
2435 const int on = 1; 3026 const int on = 1;
2436 setsockopt (socket_fd,
2437 IPPROTO_IPV6, IPV6_V6ONLY,
2438 &on, sizeof (on));
2439#else 3027#else
2440 const char on = 1; 3028 const char on = 1;
2441 setsockopt (socket_fd,
2442 IPPROTO_IPV6, IPV6_V6ONLY,
2443 &on, sizeof (on));
2444#endif 3029#endif
3030 if ( (0 > SETSOCKOPT (socket_fd,
3031 IPPROTO_IPV6, IPV6_V6ONLY,
3032 &on, sizeof (on))) &&
3033 (0 != (flags & MHD_USE_DEBUG)) )
3034 {
3035#if HAVE_MESSAGES
3036 MHD_DLOG (daemon,
3037 "setsockopt failed: %s\n",
3038 STRERROR (errno));
3039#endif
3040 }
2445#endif 3041#endif
2446#endif 3042#endif
2447 } 3043 }
@@ -2454,11 +3050,26 @@ MHD_start_daemon_va (unsigned int flags,
2454 (unsigned int) port, 3050 (unsigned int) port,
2455 STRERROR (errno)); 3051 STRERROR (errno));
2456#endif 3052#endif
2457 CLOSE (socket_fd); 3053 if (0 != CLOSE (socket_fd))
3054 MHD_PANIC ("close failed\n");
2458 goto free_and_fail; 3055 goto free_and_fail;
2459 } 3056 }
2460 3057#if EPOLL_SUPPORT
2461 if (LISTEN (socket_fd, 20) < 0) 3058 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3059 {
3060 int sk_flags = fcntl (socket_fd, F_GETFL);
3061 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3062 {
3063 MHD_DLOG (daemon,
3064 "Failed to make listen socket non-blocking: %s\n",
3065 STRERROR (errno));
3066 if (0 != CLOSE (socket_fd))
3067 MHD_PANIC ("close failed\n");
3068 goto free_and_fail;
3069 }
3070 }
3071#endif
3072 if (LISTEN (socket_fd, 32) < 0)
2462 { 3073 {
2463#if HAVE_MESSAGES 3074#if HAVE_MESSAGES
2464 if (0 != (flags & MHD_USE_DEBUG)) 3075 if (0 != (flags & MHD_USE_DEBUG))
@@ -2466,7 +3077,8 @@ MHD_start_daemon_va (unsigned int flags,
2466 "Failed to listen for connections: %s\n", 3077 "Failed to listen for connections: %s\n",
2467 STRERROR (errno)); 3078 STRERROR (errno));
2468#endif 3079#endif
2469 CLOSE (socket_fd); 3080 if (0 != CLOSE (socket_fd))
3081 MHD_PANIC ("close failed\n");
2470 goto free_and_fail; 3082 goto free_and_fail;
2471 } 3083 }
2472 } 3084 }
@@ -2476,7 +3088,7 @@ MHD_start_daemon_va (unsigned int flags,
2476 } 3088 }
2477#ifndef WINDOWS 3089#ifndef WINDOWS
2478 if ( (socket_fd >= FD_SETSIZE) && 3090 if ( (socket_fd >= FD_SETSIZE) &&
2479 (0 == (flags & MHD_USE_POLL)) ) 3091 (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
2480 { 3092 {
2481#if HAVE_MESSAGES 3093#if HAVE_MESSAGES
2482 if ((flags & MHD_USE_DEBUG) != 0) 3094 if ((flags & MHD_USE_DEBUG) != 0)
@@ -2485,7 +3097,8 @@ MHD_start_daemon_va (unsigned int flags,
2485 socket_fd, 3097 socket_fd,
2486 FD_SETSIZE); 3098 FD_SETSIZE);
2487#endif 3099#endif
2488 CLOSE (socket_fd); 3100 if (0 != CLOSE (socket_fd))
3101 MHD_PANIC ("close failed\n");
2489 goto free_and_fail; 3102 goto free_and_fail;
2490 } 3103 }
2491#endif 3104#endif
@@ -2496,8 +3109,9 @@ MHD_start_daemon_va (unsigned int flags,
2496 MHD_DLOG (daemon, 3109 MHD_DLOG (daemon,
2497 "MHD failed to initialize IP connection limit mutex\n"); 3110 "MHD failed to initialize IP connection limit mutex\n");
2498#endif 3111#endif
2499 if (-1 != socket_fd) 3112 if ( (-1 != socket_fd) &&
2500 CLOSE (socket_fd); 3113 (0 != CLOSE (socket_fd)) )
3114 MHD_PANIC ("close failed\n");
2501 goto free_and_fail; 3115 goto free_and_fail;
2502 } 3116 }
2503 if (0 != pthread_mutex_init (&daemon->cleanup_connection_mutex, NULL)) 3117 if (0 != pthread_mutex_init (&daemon->cleanup_connection_mutex, NULL))
@@ -2507,8 +3121,9 @@ MHD_start_daemon_va (unsigned int flags,
2507 "MHD failed to initialize IP connection limit mutex\n"); 3121 "MHD failed to initialize IP connection limit mutex\n");
2508#endif 3122#endif
2509 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 3123 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2510 if (-1 != socket_fd) 3124 if ( (-1 != socket_fd) &&
2511 CLOSE (socket_fd); 3125 (0 != CLOSE (socket_fd)) )
3126 MHD_PANIC ("close failed\n");
2512 goto free_and_fail; 3127 goto free_and_fail;
2513 } 3128 }
2514 3129
@@ -2520,8 +3135,9 @@ MHD_start_daemon_va (unsigned int flags,
2520 MHD_DLOG (daemon, 3135 MHD_DLOG (daemon,
2521 "Failed to initialize TLS support\n"); 3136 "Failed to initialize TLS support\n");
2522#endif 3137#endif
2523 if (-1 != socket_fd) 3138 if ( (-1 != socket_fd) &&
2524 CLOSE (socket_fd); 3139 (0 != CLOSE (socket_fd)) )
3140 MHD_PANIC ("close failed\n");
2525 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 3141 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2526 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 3142 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2527 goto free_and_fail; 3143 goto free_and_fail;
@@ -2541,8 +3157,9 @@ MHD_start_daemon_va (unsigned int flags,
2541#endif 3157#endif
2542 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 3158 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2543 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 3159 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2544 if (-1 != socket_fd) 3160 if ( (-1 != socket_fd) &&
2545 CLOSE (socket_fd); 3161 (0 != CLOSE (socket_fd)) )
3162 MHD_PANIC ("close failed\n");
2546 goto free_and_fail; 3163 goto free_and_fail;
2547 } 3164 }
2548 if ( (daemon->worker_pool_size > 0) && 3165 if ( (daemon->worker_pool_size > 0) &&
@@ -2596,8 +3213,8 @@ MHD_start_daemon_va (unsigned int flags,
2596 { 3213 {
2597 /* Create copy of the Daemon object for each worker */ 3214 /* Create copy of the Daemon object for each worker */
2598 struct MHD_Daemon *d = &daemon->worker_pool[i]; 3215 struct MHD_Daemon *d = &daemon->worker_pool[i];
2599 memcpy (d, daemon, sizeof (struct MHD_Daemon));
2600 3216
3217 memcpy (d, daemon, sizeof (struct MHD_Daemon));
2601 /* Adjust pooling params for worker daemons; note that memcpy() 3218 /* Adjust pooling params for worker daemons; note that memcpy()
2602 has already copied MHD_USE_SELECT_INTERNALLY thread model into 3219 has already copied MHD_USE_SELECT_INTERNALLY thread model into
2603 the worker threads. */ 3220 the worker threads. */
@@ -2611,7 +3228,11 @@ MHD_start_daemon_va (unsigned int flags,
2611 d->max_connections = conns_per_thread; 3228 d->max_connections = conns_per_thread;
2612 if (i < leftover_conns) 3229 if (i < leftover_conns)
2613 ++d->max_connections; 3230 ++d->max_connections;
2614 3231#if EPOLL_SUPPORT
3232 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3233 (MHD_YES != setup_epoll_to_listen (d)) )
3234 goto thread_failed;
3235#endif
2615 /* Must init cleanup connection mutex for each worker */ 3236 /* Must init cleanup connection mutex for each worker */
2616 if (0 != pthread_mutex_init (&d->cleanup_connection_mutex, NULL)) 3237 if (0 != pthread_mutex_init (&d->cleanup_connection_mutex, NULL))
2617 { 3238 {
@@ -2623,7 +3244,8 @@ MHD_start_daemon_va (unsigned int flags,
2623 } 3244 }
2624 3245
2625 /* Spawn the worker thread */ 3246 /* Spawn the worker thread */
2626 if (0 != (res_thread_create = create_thread (&d->pid, daemon, &MHD_select_thread, d))) 3247 if (0 != (res_thread_create =
3248 create_thread (&d->pid, daemon, &MHD_select_thread, d)))
2627 { 3249 {
2628#if HAVE_MESSAGES 3250#if HAVE_MESSAGES
2629 MHD_DLOG (daemon, 3251 MHD_DLOG (daemon,
@@ -2646,8 +3268,9 @@ thread_failed:
2646 MHD_USE_SELECT_INTERNALLY mode. */ 3268 MHD_USE_SELECT_INTERNALLY mode. */
2647 if (0 == i) 3269 if (0 == i)
2648 { 3270 {
2649 if (-1 != socket_fd) 3271 if ( (-1 != socket_fd) &&
2650 CLOSE (socket_fd); 3272 (0 != CLOSE (socket_fd)) )
3273 MHD_PANIC ("close failed\n");
2651 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 3274 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2652 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 3275 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2653 if (NULL != daemon->worker_pool) 3276 if (NULL != daemon->worker_pool)
@@ -2666,6 +3289,8 @@ thread_failed:
2666 free_and_fail: 3289 free_and_fail:
2667 /* clean up basic memory state in 'daemon' and return NULL to 3290 /* clean up basic memory state in 'daemon' and return NULL to
2668 indicate failure */ 3291 indicate failure */
3292 if (-1 != daemon->epoll_fd)
3293 close (daemon->epoll_fd);
2669#ifdef DAUTH_SUPPORT 3294#ifdef DAUTH_SUPPORT
2670 free (daemon->nnc); 3295 free (daemon->nnc);
2671 pthread_mutex_destroy (&daemon->nnc_lock); 3296 pthread_mutex_destroy (&daemon->nnc_lock);
@@ -2680,6 +3305,37 @@ thread_failed:
2680 3305
2681 3306
2682/** 3307/**
3308 * Close the given connection, remove it from all of its
3309 * DLLs and move it into the cleanup queue.
3310 *
3311 * @param pos connection to move to cleanup
3312 */
3313static void
3314close_connection (struct MHD_Connection *pos)
3315{
3316 struct MHD_Daemon *daemon = pos->daemon;
3317
3318 MHD_connection_close (pos,
3319 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
3320 if (pos->connection_timeout == pos->daemon->connection_timeout)
3321 XDLL_remove (daemon->normal_timeout_head,
3322 daemon->normal_timeout_tail,
3323 pos);
3324 else
3325 XDLL_remove (daemon->manual_timeout_head,
3326 daemon->manual_timeout_tail,
3327 pos);
3328 DLL_remove (daemon->connections_head,
3329 daemon->connections_tail,
3330 pos);
3331 pos->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
3332 DLL_insert (daemon->cleanup_head,
3333 daemon->cleanup_tail,
3334 pos);
3335}
3336
3337
3338/**
2683 * Close all connections for the daemon; must only be called after 3339 * Close all connections for the daemon; must only be called after
2684 * all of the threads have been joined and there is no more concurrent 3340 * all of the threads have been joined and there is no more concurrent
2685 * activity on the connection lists. 3341 * activity on the connection lists.
@@ -2695,47 +3351,61 @@ close_all_connections (struct MHD_Daemon *daemon)
2695 3351
2696 /* first, make sure all threads are aware of shutdown; need to 3352 /* first, make sure all threads are aware of shutdown; need to
2697 traverse DLLs in peace... */ 3353 traverse DLLs in peace... */
2698 if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) 3354 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2699 { 3355 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
2700 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 3356 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2701 } 3357 for (pos = daemon->connections_head; NULL != pos; pos = pos->nextX)
2702 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2703 SHUTDOWN (pos->socket_fd, 3358 SHUTDOWN (pos->socket_fd,
2704 (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR); 3359 (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
2705 if (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) 3360 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2706 { 3361 (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
2707 MHD_PANIC ("Failed to release cleanup mutex\n"); 3362 MHD_PANIC ("Failed to release cleanup mutex\n");
2708 }
2709 3363
2710 /* now, collect threads */ 3364 /* now, collect threads from thread pool */
2711 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 3365 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2712 { 3366 {
2713 while (NULL != (pos = daemon->connections_head)) 3367 while (NULL != (pos = daemon->connections_head))
2714 { 3368 {
2715 if (0 != (rc = pthread_join (pos->pid, &unused))) 3369 if (0 != (rc = pthread_join (pos->pid, &unused)))
2716 { 3370 MHD_PANIC ("Failed to join a thread\n");
2717 MHD_PANIC ("Failed to join a thread\n");
2718 }
2719 pos->thread_joined = MHD_YES; 3371 pos->thread_joined = MHD_YES;
2720 } 3372 }
2721 } 3373 }
2722 3374
2723 /* now that we're alone, move everyone to cleanup */ 3375 /* now that we're alone, move everyone to cleanup */
2724 while (NULL != (pos = daemon->connections_head)) 3376 while (NULL != (pos = daemon->connections_head))
2725 { 3377 close_connection (pos);
2726 MHD_connection_close (pos,
2727 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
2728 DLL_remove (daemon->connections_head,
2729 daemon->connections_tail,
2730 pos);
2731 DLL_insert (daemon->cleanup_head,
2732 daemon->cleanup_tail,
2733 pos);
2734 }
2735 MHD_cleanup_connections (daemon); 3378 MHD_cleanup_connections (daemon);
2736} 3379}
2737 3380
2738 3381
3382#if EPOLL_SUPPORT
3383/**
3384 * Shutdown 'epoll' event loop by adding 'wpipe' to its event set.
3385 *
3386 * @param daemon daemon of which the epoll instance must be signalled
3387 */
3388static void
3389epoll_shutdown (struct MHD_Daemon *daemon)
3390{
3391 struct epoll_event event;
3392
3393 if (-1 == daemon->wpipe[1])
3394 {
3395 /* wpipe was required in this mode, how could this happen? */
3396 MHD_PANIC ("Internal error\n");
3397 }
3398 event.events = EPOLLOUT;
3399 event.data.ptr = NULL;
3400 if (0 != epoll_ctl (daemon->epoll_fd,
3401 EPOLL_CTL_ADD,
3402 daemon->wpipe[1],
3403 &event))
3404 MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
3405}
3406#endif
3407
3408
2739/** 3409/**
2740 * Shutdown an http daemon 3410 * Shutdown an http daemon
2741 * 3411 *
@@ -2762,6 +3432,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2762 { 3432 {
2763 daemon->worker_pool[i].shutdown = MHD_YES; 3433 daemon->worker_pool[i].shutdown = MHD_YES;
2764 daemon->worker_pool[i].socket_fd = -1; 3434 daemon->worker_pool[i].socket_fd = -1;
3435#if EPOLL_SUPPORT
3436 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3437 (-1 != daemon->worker_pool[i].epoll_fd) &&
3438 (-1 == fd) )
3439 epoll_shutdown (&daemon->worker_pool[i]);
3440#endif
2765 } 3441 }
2766 } 3442 }
2767 if (-1 != daemon->wpipe[1]) 3443 if (-1 != daemon->wpipe[1])
@@ -2777,6 +3453,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2777 (void) SHUTDOWN (fd, SHUT_RDWR); 3453 (void) SHUTDOWN (fd, SHUT_RDWR);
2778 } 3454 }
2779#endif 3455#endif
3456#if EPOLL_SUPPORT
3457 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3458 (-1 != daemon->epoll_fd) &&
3459 (-1 == fd) )
3460 epoll_shutdown (daemon);
3461#endif
3462
2780#if DEBUG_CLOSE 3463#if DEBUG_CLOSE
2781#if HAVE_MESSAGES 3464#if HAVE_MESSAGES
2782 MHD_DLOG (daemon, "MHD listen socket shutdown\n"); 3465 MHD_DLOG (daemon, "MHD listen socket shutdown\n");
@@ -2790,12 +3473,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2790 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */ 3473 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
2791 for (i = 0; i < daemon->worker_pool_size; ++i) 3474 for (i = 0; i < daemon->worker_pool_size; ++i)
2792 { 3475 {
2793 if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused))) 3476 if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
2794 { 3477 MHD_PANIC ("Failed to join a thread\n");
2795 MHD_PANIC ("Failed to join a thread\n"); 3478 close_all_connections (&daemon->worker_pool[i]);
2796 }
2797 close_all_connections (&daemon->worker_pool[i]);
2798 pthread_mutex_destroy (&daemon->worker_pool[i].cleanup_connection_mutex); 3479 pthread_mutex_destroy (&daemon->worker_pool[i].cleanup_connection_mutex);
3480 if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
3481 (0 != CLOSE (daemon->worker_pool[i].epoll_fd)) )
3482 MHD_PANIC ("close failed\n");
2799 } 3483 }
2800 free (daemon->worker_pool); 3484 free (daemon->worker_pool);
2801 } 3485 }
@@ -2813,8 +3497,9 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2813 } 3497 }
2814 } 3498 }
2815 close_all_connections (daemon); 3499 close_all_connections (daemon);
2816 if (-1 != fd) 3500 if ( (-1 != fd) &&
2817 (void) CLOSE (fd); 3501 (0 != CLOSE (fd)) )
3502 MHD_PANIC ("close failed\n");
2818 3503
2819 /* TLS clean up */ 3504 /* TLS clean up */
2820#if HTTPS_SUPPORT 3505#if HTTPS_SUPPORT
@@ -2825,6 +3510,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2825 gnutls_certificate_free_credentials (daemon->x509_cred); 3510 gnutls_certificate_free_credentials (daemon->x509_cred);
2826 } 3511 }
2827#endif 3512#endif
3513#if EPOLL_SUPPORT
3514 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3515 (-1 != daemon->epoll_fd) &&
3516 (0 != CLOSE (daemon->epoll_fd)) )
3517 MHD_PANIC ("close failed\n");
3518#endif
2828 3519
2829#ifdef DAUTH_SUPPORT 3520#ifdef DAUTH_SUPPORT
2830 free (daemon->nnc); 3521 free (daemon->nnc);
@@ -2835,8 +3526,10 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
2835 3526
2836 if (-1 != daemon->wpipe[1]) 3527 if (-1 != daemon->wpipe[1])
2837 { 3528 {
2838 (void) CLOSE (daemon->wpipe[0]); 3529 if (0 != CLOSE (daemon->wpipe[0]))
2839 (void) CLOSE (daemon->wpipe[1]); 3530 MHD_PANIC ("close failed\n");
3531 if (0 != CLOSE (daemon->wpipe[1]))
3532 MHD_PANIC ("close failed\n");
2840 } 3533 }
2841 free (daemon); 3534 free (daemon);
2842} 3535}
@@ -2858,8 +3551,16 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
2858{ 3551{
2859 switch (infoType) 3552 switch (infoType)
2860 { 3553 {
3554 case MHD_DAEMON_INFO_KEY_SIZE:
3555 return NULL; /* no longer supported */
3556 case MHD_DAEMON_INFO_MAC_KEY_SIZE:
3557 return NULL; /* no longer supported */
2861 case MHD_DAEMON_INFO_LISTEN_FD: 3558 case MHD_DAEMON_INFO_LISTEN_FD:
2862 return (const union MHD_DaemonInfo *) &daemon->socket_fd; 3559 return (const union MHD_DaemonInfo *) &daemon->socket_fd;
3560#if EPOLL_SUPPORT
3561 case MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY:
3562 return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
3563#endif
2863 default: 3564 default:
2864 return NULL; 3565 return NULL;
2865 }; 3566 };
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 88f7c5d3..4603050a 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 (C) 2007, 2008, 2009, 2010, 2011, 2012 Daniel Pittman and Christian Grothoff 3 (C) 2007-2013 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -32,6 +32,10 @@
32#if HTTPS_SUPPORT 32#if HTTPS_SUPPORT
33#include <gnutls/gnutls.h> 33#include <gnutls/gnutls.h>
34#endif 34#endif
35#if EPOLL_SUPPORT
36#include <sys/epoll.h>
37#endif
38
35 39
36/** 40/**
37 * Should we perform additional sanity checks at runtime (on our internal 41 * Should we perform additional sanity checks at runtime (on our internal
@@ -69,63 +73,67 @@ extern void *mhd_panic_cls;
69#define MHD_PANIC(msg) mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL) 73#define MHD_PANIC(msg) mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL)
70#endif 74#endif
71 75
76
72/** 77/**
73 * Events we care about with respect to poll/select 78 * State of the socket with respect to epoll (bitmask).
74 * for file descriptors.
75 */ 79 */
76enum MHD_PollActions 80enum MHD_EpollState
77 { 81 {
82
78 /** 83 /**
79 * No event interests us. 84 * The socket is not involved with a defined state in epoll right
85 * now.
80 */ 86 */
81 MHD_POLL_ACTION_NOTHING = 0, 87 MHD_EPOLL_STATE_UNREADY = 0,
82 88
83 /** 89 /**
84 * We would like to read. 90 * epoll told us that data was ready for reading, and we did
91 * not consume all of it yet.
85 */ 92 */
86 MHD_POLL_ACTION_IN = 1, 93 MHD_EPOLL_STATE_READ_READY = 1,
87 94
88 /** 95 /**
89 * We would like to write. 96 * epoll told us that space was available for writing, and we did
90 */ 97 * not consume all of it yet.
91 MHD_POLL_ACTION_OUT = 2 98 */
99 MHD_EPOLL_STATE_WRITE_READY = 2,
100
101 /**
102 * Is this connection currently in the 'eready' EDLL?
103 */
104 MHD_EPOLL_STATE_IN_EREADY_EDLL = 4
105
92 }; 106 };
93 107
94 108
95/** 109/**
96 * State of the socket with respect to epoll. 110 * What is this connection waiting for?
97 */ 111 */
98enum MHD_EpollState 112enum MHD_ConnectionEventLoopInfo
99 { 113 {
100
101 /** 114 /**
102 * 115 * We are waiting to be able to read.
103 */ 116 */
104 MHD_EPOLL_STATE_NOTHING = 0 117 MHD_EVENT_LOOP_INFO_READ = 0,
105 118
119 /**
120 * We are waiting to be able to write.
121 */
122 MHD_EVENT_LOOP_INFO_WRITE = 1,
106 123
124 /**
125 * We are waiting for the application to provide data.
126 */
127 MHD_EVENT_LOOP_INFO_BLOCK = 2,
107 128
129 /**
130 * We are finished and are awaiting cleanup.
131 */
132 MHD_EVENT_LOOP_INFO_CLEANUP = 3
108 }; 133 };
109 134
110 135
111/** 136/**
112 * Socket descriptor and events we care about.
113 */
114struct MHD_Pollfd
115{
116 /**
117 * Socket descriptor.
118 */
119 int fd;
120
121 /**
122 * Which events do we care about for this socket?
123 */
124 enum MHD_PollActions events;
125};
126
127
128/**
129 * Maximum length of a nonce in digest authentication. 32(MD5 Hex) + 137 * Maximum length of a nonce in digest authentication. 32(MD5 Hex) +
130 * 8(Timestamp Hex) + 1(NULL); hence 41 should suffice, but Opera 138 * 8(Timestamp Hex) + 1(NULL); hence 41 should suffice, but Opera
131 * (already) takes more (see Mantis #1633), so we've increased the 139 * (already) takes more (see Mantis #1633), so we've increased the
@@ -477,17 +485,39 @@ typedef ssize_t (*TransmitCallback) (struct MHD_Connection * conn,
477struct MHD_Connection 485struct MHD_Connection
478{ 486{
479 487
488#if EPOLL_SUPPORT
480 /** 489 /**
481 * This is a doubly-linked list. 490 * Next pointer for the EDLL listing connections that are epoll-ready.
491 */
492 struct MHD_Connection *nextE;
493
494 /**
495 * Previous pointer for the EDLL listing connections that are epoll-ready.
496 */
497 struct MHD_Connection *prevE;
498#endif
499
500 /**
501 * Next pointer for the DLL describing our IO state.
482 */ 502 */
483 struct MHD_Connection *next; 503 struct MHD_Connection *next;
484 504
485 /** 505 /**
486 * This is a doubly-linked list. 506 * Previous pointer for the DLL describing our IO state.
487 */ 507 */
488 struct MHD_Connection *prev; 508 struct MHD_Connection *prev;
489 509
490 /** 510 /**
511 * Next pointer for the XDLL organizing connections by timeout.
512 */
513 struct MHD_Connection *nextX;
514
515 /**
516 * Previous pointer for the XDLL organizing connections by timeout.
517 */
518 struct MHD_Connection *prevX;
519
520 /**
491 * Reference to the MHD_Daemon struct. 521 * Reference to the MHD_Daemon struct.
492 */ 522 */
493 struct MHD_Daemon *daemon; 523 struct MHD_Daemon *daemon;
@@ -667,11 +697,10 @@ struct MHD_Connection
667 int socket_fd; 697 int socket_fd;
668 698
669 /** 699 /**
670 * Has this socket been closed for reading (i.e. 700 * Has this socket been closed for reading (i.e. other side closed
671 * other side closed the connection)? If so, 701 * the connection)? If so, we must completely close the connection
672 * we must completely close the connection once 702 * once we are done sending our response (and stop trying to read
673 * we are done sending our response (and stop 703 * from this socket).
674 * trying to read from this socket).
675 */ 704 */
676 int read_closed; 705 int read_closed;
677 706
@@ -680,12 +709,24 @@ struct MHD_Connection
680 */ 709 */
681 int thread_joined; 710 int thread_joined;
682 711
712#if EPOLL_SUPPORT
713 /**
714 * What is the state of this socket in relation to epoll?
715 */
716 enum MHD_EpollState epoll_state;
717#endif
718
683 /** 719 /**
684 * State in the FSM for this connection. 720 * State in the FSM for this connection.
685 */ 721 */
686 enum MHD_CONNECTION_STATE state; 722 enum MHD_CONNECTION_STATE state;
687 723
688 /** 724 /**
725 * What is this connection waiting for?
726 */
727 enum MHD_ConnectionEventLoopInfo event_loop_info;
728
729 /**
689 * HTTP response code. Only valid if response object 730 * HTTP response code. Only valid if response object
690 * is already set. 731 * is already set.
691 */ 732 */
@@ -797,7 +838,11 @@ typedef size_t (*UnescapeCallback)(void *cls,
797 838
798 839
799/** 840/**
800 * State kept for each MHD daemon. 841 * State kept for each MHD daemon. All connections are kept in two
842 * doubly-linked lists. The first one reflects the state of the
843 * connection in terms of what operations we are waiting for (read,
844 * write, locally blocked, cleanup) whereas the second is about its
845 * timeout state (default or custom).
801 */ 846 */
802struct MHD_Daemon 847struct MHD_Daemon
803{ 848{
@@ -813,7 +858,7 @@ struct MHD_Daemon
813 void *default_handler_cls; 858 void *default_handler_cls;
814 859
815 /** 860 /**
816 * Tail of doubly-linked list of our current, active connections. 861 * Head of doubly-linked list of our current, active connections.
817 */ 862 */
818 struct MHD_Connection *connections_head; 863 struct MHD_Connection *connections_head;
819 864
@@ -823,7 +868,7 @@ struct MHD_Daemon
823 struct MHD_Connection *connections_tail; 868 struct MHD_Connection *connections_tail;
824 869
825 /** 870 /**
826 * Tail of doubly-linked list of connections to clean up. 871 * Head of doubly-linked list of connections to clean up.
827 */ 872 */
828 struct MHD_Connection *cleanup_head; 873 struct MHD_Connection *cleanup_head;
829 874
@@ -832,10 +877,54 @@ struct MHD_Daemon
832 */ 877 */
833 struct MHD_Connection *cleanup_tail; 878 struct MHD_Connection *cleanup_tail;
834 879
880#if EPOLL_SUPPORT
881 /**
882 * Head of EDLL of connections ready for processing (in epoll mode).
883 */
884 struct MHD_Connection *eready_head;
885
886 /**
887 * Tail of EDLL of connections ready for processing (in epoll mode)
888 */
889 struct MHD_Connection *eready_tail;
890#endif
891
892 /**
893 * Head of the XDLL of ALL connections with a default ('normal')
894 * timeout, sorted by timeout (earliest at the tail, most recently
895 * used connection at the head). MHD can just look at the tail of
896 * this list to determine the timeout for all of its elements;
897 * whenever there is an event of a connection, the connection is
898 * moved back to the tail of the list.
899 *
900 * All connections by default start in this list; if a custom
901 * timeout that does not match 'connection_timeout' is set, they
902 * are moved to the 'manual_timeout_head'-XDLL.
903 */
904 struct MHD_Connection *normal_timeout_head;
905
906 /**
907 * Tail of the XDLL of ALL connections with a default timeout,
908 * sorted by timeout (earliest timeout at the tail).
909 */
910 struct MHD_Connection *normal_timeout_tail;
911
912 /**
913 * Head of the XDLL of ALL connections with a non-default/custom
914 * timeout, unsorted. MHD will do a O(n) scan over this list to
915 * determine the current timeout.
916 */
917 struct MHD_Connection *manual_timeout_head;
918
835 /** 919 /**
836 * Function to call to check if we should 920 * Tail of the XDLL of ALL connections with a non-default/custom
837 * accept or reject an incoming request. 921 * timeout, unsorted.
838 * May be NULL. 922 */
923 struct MHD_Connection *manual_timeout_tail;
924
925 /**
926 * Function to call to check if we should accept or reject an
927 * incoming request. May be NULL.
839 */ 928 */
840 MHD_AcceptPolicyCallback apc; 929 MHD_AcceptPolicyCallback apc;
841 930
@@ -942,6 +1031,19 @@ struct MHD_Daemon
942 */ 1031 */
943 int socket_fd; 1032 int socket_fd;
944 1033
1034#if EPOLL_SUPPORT
1035 /**
1036 * File descriptor associated with our epoll loop.
1037 */
1038 int epoll_fd;
1039
1040 /**
1041 * MHD_YES if the listen socket is in the 'epoll' set,
1042 * MHD_NO if not.
1043 */
1044 int listen_socket_in_epoll;
1045#endif
1046
945 /** 1047 /**
946 * Pipe we use to signal shutdown, unless 1048 * Pipe we use to signal shutdown, unless
947 * 'HAVE_LISTEN_SHUTDOWN' is defined AND we have a listen 1049 * 'HAVE_LISTEN_SHUTDOWN' is defined AND we have a listen
@@ -1018,6 +1120,14 @@ struct MHD_Daemon
1018 */ 1120 */
1019 const char *https_mem_trust; 1121 const char *https_mem_trust;
1020 1122
1123 /**
1124 * For how many connections do we have 'tls_read_ready' set to MHD_YES?
1125 * Used to avoid O(n) traversal over all connections when determining
1126 * event-loop timeout (as it needs to be zero if there is any connection
1127 * which might have ready data within TLS).
1128 */
1129 unsigned int num_tls_read_ready;
1130
1021#endif 1131#endif
1022 1132
1023#ifdef DAUTH_SUPPORT 1133#ifdef DAUTH_SUPPORT
@@ -1099,10 +1209,93 @@ struct MHD_Daemon
1099 (element)->prev = NULL; } while (0) 1209 (element)->prev = NULL; } while (0)
1100 1210
1101 1211
1212
1213/**
1214 * Insert an element at the head of a XDLL. Assumes that head, tail and
1215 * element are structs with prevX and nextX fields.
1216 *
1217 * @param head pointer to the head of the XDLL
1218 * @param tail pointer to the tail of the XDLL
1219 * @param element element to insert
1220 */
1221#define XDLL_insert(head,tail,element) do { \
1222 (element)->nextX = (head); \
1223 (element)->prevX = NULL; \
1224 if ((tail) == NULL) \
1225 (tail) = element; \
1226 else \
1227 (head)->prevX = element; \
1228 (head) = (element); } while (0)
1229
1230
1231/**
1232 * Remove an element from a XDLL. Assumes
1233 * that head, tail and element are structs
1234 * with prevX and nextX fields.
1235 *
1236 * @param head pointer to the head of the XDLL
1237 * @param tail pointer to the tail of the XDLL
1238 * @param element element to remove
1239 */
1240#define XDLL_remove(head,tail,element) do { \
1241 if ((element)->prevX == NULL) \
1242 (head) = (element)->nextX; \
1243 else \
1244 (element)->prevX->nextX = (element)->nextX; \
1245 if ((element)->nextX == NULL) \
1246 (tail) = (element)->prevX; \
1247 else \
1248 (element)->nextX->prevX = (element)->prevX; \
1249 (element)->nextX = NULL; \
1250 (element)->prevX = NULL; } while (0)
1251
1252
1253/**
1254 * Insert an element at the head of a EDLL. Assumes that head, tail and
1255 * element are structs with prevE and nextE fields.
1256 *
1257 * @param head pointer to the head of the EDLL
1258 * @param tail pointer to the tail of the EDLL
1259 * @param element element to insert
1260 */
1261#define EDLL_insert(head,tail,element) do { \
1262 (element)->nextE = (head); \
1263 (element)->prevE = NULL; \
1264 if ((tail) == NULL) \
1265 (tail) = element; \
1266 else \
1267 (head)->prevE = element; \
1268 (head) = (element); } while (0)
1269
1270
1271/**
1272 * Remove an element from a EDLL. Assumes
1273 * that head, tail and element are structs
1274 * with prevE and nextE fields.
1275 *
1276 * @param head pointer to the head of the EDLL
1277 * @param tail pointer to the tail of the EDLL
1278 * @param element element to remove
1279 */
1280#define EDLL_remove(head,tail,element) do { \
1281 if ((element)->prevE == NULL) \
1282 (head) = (element)->nextE; \
1283 else \
1284 (element)->prevE->nextE = (element)->nextE; \
1285 if ((element)->nextE == NULL) \
1286 (tail) = (element)->prevE; \
1287 else \
1288 (element)->nextE->prevE = (element)->prevE; \
1289 (element)->nextE = NULL; \
1290 (element)->prevE = NULL; } while (0)
1291
1292
1102/** 1293/**
1103 * Equivalent to time(NULL) but tries to use some sort of monotonic 1294 * Equivalent to time(NULL) but tries to use some sort of monotonic
1104 * clock that isn't affected by someone setting the system real time 1295 * clock that isn't affected by someone setting the system real time
1105 * clock. 1296 * clock.
1297 *
1298 * @return 'current' time
1106 */ 1299 */
1107time_t MHD_monotonic_time(void); 1300time_t MHD_monotonic_time(void);
1108 1301
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index bd7c0c3a..db347056 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -90,10 +90,13 @@ MHD_pool_create (size_t max)
90 90
91 pool = malloc (sizeof (struct MemoryPool)); 91 pool = malloc (sizeof (struct MemoryPool));
92 if (pool == NULL) 92 if (pool == NULL)
93 return NULL; 93 return NULL;
94#ifdef MAP_ANONYMOUS 94#ifdef MAP_ANONYMOUS
95 pool->memory = MMAP (NULL, max, PROT_READ | PROT_WRITE, 95 if (max <= 32 * 1024)
96 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 96 pool->memory = MAP_FAILED;
97 else
98 pool->memory = MMAP (NULL, max, PROT_READ | PROT_WRITE,
99 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
97#else 100#else
98 pool->memory = MAP_FAILED; 101 pool->memory = MAP_FAILED;
99#endif 102#endif
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 61bc5169..329950fa 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -28,8 +28,8 @@ endif
28 28
29check_PROGRAMS = \ 29check_PROGRAMS = \
30 test_start_stop \ 30 test_start_stop \
31 test_get \
32 test_quiesce \ 31 test_quiesce \
32 test_get \
33 test_get_sendfile \ 33 test_get_sendfile \
34 test_urlparse \ 34 test_urlparse \
35 test_put \ 35 test_put \
@@ -52,6 +52,8 @@ check_PROGRAMS = \
52 $(CURL_FORK_TEST) \ 52 $(CURL_FORK_TEST) \
53 perf_get $(PERF_GET_CONCURRENT) 53 perf_get $(PERF_GET_CONCURRENT)
54 54
55
56
55if HAVE_POSTPROCESSOR 57if HAVE_POSTPROCESSOR
56 check_PROGRAMS += \ 58 check_PROGRAMS += \
57 test_post \ 59 test_post \
diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c
index 77c3193e..54f383ca 100644
--- a/src/testcurl/perf_get.c
+++ b/src/testcurl/perf_get.c
@@ -219,7 +219,8 @@ testInternalGet (int port, int poll_flag)
219 } 219 }
220 curl_easy_cleanup (c); 220 curl_easy_cleanup (c);
221 } 221 }
222 stop (poll_flag ? "internal poll" : "internal select"); 222 stop (poll_flag == MHD_USE_POLL ? "internal poll" :
223 poll_flag == MHD_USE_EPOLL_LINUX_ONLY ? "internal epoll" : "internal select");
223 MHD_stop_daemon (d); 224 MHD_stop_daemon (d);
224 if (cbc.pos != strlen ("/hello_world")) 225 if (cbc.pos != strlen ("/hello_world"))
225 return 4; 226 return 4;
@@ -278,7 +279,8 @@ testMultithreadedGet (int port, int poll_flag)
278 } 279 }
279 curl_easy_cleanup (c); 280 curl_easy_cleanup (c);
280 } 281 }
281 stop (poll_flag ? "thread with poll" : "thread with select"); 282 stop ((poll_flag & MHD_USE_POLL) ? "thread with poll" :
283 (poll_flag & MHD_USE_EPOLL_LINUX_ONLY) ? "thread with epoll" : "thread with select");
282 MHD_stop_daemon (d); 284 MHD_stop_daemon (d);
283 if (cbc.pos != strlen ("/hello_world")) 285 if (cbc.pos != strlen ("/hello_world"))
284 return 64; 286 return 64;
@@ -337,7 +339,8 @@ testMultithreadedPoolGet (int port, int poll_flag)
337 } 339 }
338 curl_easy_cleanup (c); 340 curl_easy_cleanup (c);
339 } 341 }
340 stop (poll_flag ? "thread pool with poll" : "thread pool with select"); 342 stop (0 != (poll_flag & MHD_USE_POLL) ? "thread pool with poll" :
343 0 != (poll_flag & MHD_USE_EPOLL_LINUX_ONLY) ? "thread pool with epoll" : "thread pool with select");
341 MHD_stop_daemon (d); 344 MHD_stop_daemon (d);
342 if (cbc.pos != strlen ("/hello_world")) 345 if (cbc.pos != strlen ("/hello_world"))
343 return 64; 346 return 64;
@@ -507,6 +510,10 @@ main (int argc, char *const *argv)
507 errorCount += testMultithreadedGet (port++, MHD_USE_POLL); 510 errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
508 errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL); 511 errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
509#endif 512#endif
513#if EPOLL_SUPPORT
514 errorCount += testInternalGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
515 errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
516#endif
510 MHD_destroy_response (response); 517 MHD_destroy_response (response);
511 if (errorCount != 0) 518 if (errorCount != 0)
512 fprintf (stderr, "Error (code: %u)\n", errorCount); 519 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/perf_get_concurrent.c b/src/testcurl/perf_get_concurrent.c
index 85086bbe..15616ad5 100644
--- a/src/testcurl/perf_get_concurrent.c
+++ b/src/testcurl/perf_get_concurrent.c
@@ -336,6 +336,10 @@ main (int argc, char *const *argv)
336 errorCount += testMultithreadedGet (port++, MHD_USE_POLL); 336 errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
337 errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL); 337 errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
338#endif 338#endif
339#if EPOLL_SUPPORT
340 errorCount += testInternalGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
341 errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
342#endif
339 MHD_destroy_response (response); 343 MHD_destroy_response (response);
340 if (errorCount != 0) 344 if (errorCount != 0)
341 fprintf (stderr, "Error (code: %u)\n", errorCount); 345 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
index 45122cdb..ad9cbe14 100644
--- a/src/testcurl/test_get.c
+++ b/src/testcurl/test_get.c
@@ -145,6 +145,7 @@ testInternalGet (int poll_flag)
145 return 0; 145 return 0;
146} 146}
147 147
148
148static int 149static int
149testMultithreadedGet (int poll_flag) 150testMultithreadedGet (int poll_flag)
150{ 151{
@@ -194,6 +195,7 @@ testMultithreadedGet (int poll_flag)
194 return 0; 195 return 0;
195} 196}
196 197
198
197static int 199static int
198testMultithreadedPoolGet (int poll_flag) 200testMultithreadedPoolGet (int poll_flag)
199{ 201{
@@ -244,6 +246,7 @@ testMultithreadedPoolGet (int poll_flag)
244 return 0; 246 return 0;
245} 247}
246 248
249
247static int 250static int
248testExternalGet () 251testExternalGet ()
249{ 252{
@@ -366,6 +369,7 @@ testExternalGet ()
366 return 0; 369 return 0;
367} 370}
368 371
372
369static int 373static int
370testUnknownPortGet (int poll_flag) 374testUnknownPortGet (int poll_flag)
371{ 375{
@@ -506,6 +510,11 @@ main (int argc, char *const *argv)
506 errorCount += testUnknownPortGet (MHD_USE_POLL); 510 errorCount += testUnknownPortGet (MHD_USE_POLL);
507 errorCount += testStopRace (MHD_USE_POLL); 511 errorCount += testStopRace (MHD_USE_POLL);
508#endif 512#endif
513#if EPOLL_SUPPORT
514 errorCount += testInternalGet (MHD_USE_EPOLL_LINUX_ONLY);
515 errorCount += testMultithreadedPoolGet (MHD_USE_EPOLL_LINUX_ONLY);
516 errorCount += testUnknownPortGet (MHD_USE_EPOLL_LINUX_ONLY);
517#endif
509 if (errorCount != 0) 518 if (errorCount != 0)
510 fprintf (stderr, "Error (code: %u)\n", errorCount); 519 fprintf (stderr, "Error (code: %u)\n", errorCount);
511 curl_global_cleanup (); 520 curl_global_cleanup ();
diff --git a/src/testcurl/test_quiesce.c b/src/testcurl/test_quiesce.c
index 4755de92..dc131439 100644
--- a/src/testcurl/test_quiesce.c
+++ b/src/testcurl/test_quiesce.c
@@ -31,6 +31,8 @@
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33#include <time.h> 33#include <time.h>
34#include <sys/types.h>
35#include <sys/wait.h>
34 36
35#ifndef WINDOWS 37#ifndef WINDOWS
36#include <unistd.h> 38#include <unistd.h>
@@ -38,7 +40,7 @@
38#endif 40#endif
39 41
40static int oneone; 42static int oneone;
41static int done; 43
42 44
43struct CBC 45struct CBC
44{ 46{
@@ -47,6 +49,7 @@ struct CBC
47 size_t size; 49 size_t size;
48}; 50};
49 51
52
50static size_t 53static size_t
51copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) 54copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
52{ 55{
@@ -59,6 +62,7 @@ copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
59 return size * nmemb; 62 return size * nmemb;
60} 63}
61 64
65
62static int 66static int
63ahc_echo (void *cls, 67ahc_echo (void *cls,
64 struct MHD_Connection *connection, 68 struct MHD_Connection *connection,
@@ -91,24 +95,28 @@ ahc_echo (void *cls,
91 return ret; 95 return ret;
92} 96}
93 97
94void request_completed (void *cls, struct MHD_Connection *connection, 98
95 void **con_cls, enum MHD_RequestTerminationCode code) 99static void
100request_completed (void *cls, struct MHD_Connection *connection,
101 void **con_cls, enum MHD_RequestTerminationCode code)
96{ 102{
97 int *done = (int *)cls; 103 int *done = (int *)cls;
98 *done = 1; 104 *done = 1;
99} 105}
100 106
101void ServeOneRequest(int fd) 107
108static void
109ServeOneRequest(int fd)
102{ 110{
103 struct MHD_Daemon *d; 111 struct MHD_Daemon *d;
104 fd_set rs; 112 fd_set rs;
105 fd_set ws; 113 fd_set ws;
106 fd_set es; 114 fd_set es;
107 int max; 115 int max;
108 struct CURLMsg *msg;
109 time_t start; 116 time_t start;
110 struct timeval tv; 117 struct timeval tv;
111 int done = 0; 118 int done = 0;
119
112 d = MHD_start_daemon (MHD_USE_DEBUG, 120 d = MHD_start_daemon (MHD_USE_DEBUG,
113 1082, NULL, NULL, &ahc_echo, "GET", 121 1082, NULL, NULL, &ahc_echo, "GET",
114 MHD_OPTION_LISTEN_SOCKET, fd, 122 MHD_OPTION_LISTEN_SOCKET, fd,
@@ -140,9 +148,12 @@ void ServeOneRequest(int fd)
140 _exit(0); 148 _exit(0);
141} 149}
142 150
143CURL *setupCURL(void *cbc) 151
152static CURL *
153setupCURL (void *cbc)
144{ 154{
145 CURL *c; 155 CURL *c;
156
146 c = curl_easy_init (); 157 c = curl_easy_init ();
147 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world"); 158 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
148 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); 159 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
@@ -162,6 +173,7 @@ CURL *setupCURL(void *cbc)
162 return c; 173 return c;
163} 174}
164 175
176
165static int 177static int
166testGet (int type, int pool_count, int poll_flag) 178testGet (int type, int pool_count, int poll_flag)
167{ 179{
@@ -171,18 +183,17 @@ testGet (int type, int pool_count, int poll_flag)
171 struct CBC cbc; 183 struct CBC cbc;
172 CURLcode errornum; 184 CURLcode errornum;
173 int fd; 185 int fd;
174 pid_t pid;
175 186
176 cbc.buf = buf; 187 cbc.buf = buf;
177 cbc.size = 2048; 188 cbc.size = 2048;
178 cbc.pos = 0; 189 cbc.pos = 0;
179 if (pool_count > 0) { 190 if (pool_count > 0) {
180 d = MHD_start_daemon (type | MHD_USE_DEBUG | poll_flag, 191 d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
181 11080, NULL, NULL, &ahc_echo, "GET", 192 11080, NULL, NULL, &ahc_echo, "GET",
182 MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END); 193 MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END);
183 194
184 } else { 195 } else {
185 d = MHD_start_daemon (type | MHD_USE_DEBUG | poll_flag, 196 d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
186 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); 197 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
187 } 198 }
188 if (d == NULL) 199 if (d == NULL)
@@ -211,12 +222,12 @@ testGet (int type, int pool_count, int poll_flag)
211 return 8; 222 return 8;
212 } 223 }
213 224
214 fd = MHD_quiesce_daemon(d); 225 fd = MHD_quiesce_daemon (d);
215 226 if (fork() == 0)
216 if (fork() == 0) { 227 {
217 ServeOneRequest(fd); 228 ServeOneRequest (fd);
218 _exit(1); 229 _exit(1);
219 } 230 }
220 231
221 cbc.pos = 0; 232 cbc.pos = 0;
222 if (CURLE_OK != (errornum = curl_easy_perform (c))) 233 if (CURLE_OK != (errornum = curl_easy_perform (c)))
@@ -225,25 +236,28 @@ testGet (int type, int pool_count, int poll_flag)
225 "curl_easy_perform failed: `%s'\n", 236 "curl_easy_perform failed: `%s'\n",
226 curl_easy_strerror (errornum)); 237 curl_easy_strerror (errornum));
227 curl_easy_cleanup (c); 238 curl_easy_cleanup (c);
239 MHD_stop_daemon (d);
228 return 2; 240 return 2;
229 } 241 }
230 242
231 waitpid(-1, NULL, 0); 243 waitpid(-1, NULL, 0);
232 244
233 if (cbc.pos != strlen ("/hello_world")) { 245 if (cbc.pos != strlen ("/hello_world"))
234 fprintf(stderr, "%s\n", cbc.buf); 246 {
235 curl_easy_cleanup (c); 247 fprintf(stderr, "%s\n", cbc.buf);
236 MHD_stop_daemon (d); 248 curl_easy_cleanup (c);
237 close(fd); 249 MHD_stop_daemon (d);
238 return 4; 250 close(fd);
239 } 251 return 4;
240 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) { 252 }
241 fprintf(stderr, "%s\n", cbc.buf); 253 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
242 curl_easy_cleanup (c); 254 {
243 MHD_stop_daemon (d); 255 fprintf(stderr, "%s\n", cbc.buf);
244 close(fd); 256 curl_easy_cleanup (c);
245 return 8; 257 MHD_stop_daemon (d);
246 } 258 close(fd);
259 return 8;
260 }
247 261
248 /* at this point, the forked server quit, and the new 262 /* at this point, the forked server quit, and the new
249 * server has quiesced, so new requests should fail 263 * server has quiesced, so new requests should fail
@@ -408,6 +422,10 @@ main (int argc, char *const *argv)
408 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, MHD_USE_POLL); 422 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, MHD_USE_POLL);
409 errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 4, MHD_USE_POLL); 423 errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 4, MHD_USE_POLL);
410#endif 424#endif
425#if EPOLL_SUPPORT
426 errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 0, MHD_USE_EPOLL_LINUX_ONLY);
427 errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 4, MHD_USE_EPOLL_LINUX_ONLY);
428#endif
411 if (errorCount != 0) 429 if (errorCount != 0)
412 fprintf (stderr, "Error (code: %u)\n", errorCount); 430 fprintf (stderr, "Error (code: %u)\n", errorCount);
413 curl_global_cleanup (); 431 curl_global_cleanup ();
diff --git a/src/testcurl/test_start_stop.c b/src/testcurl/test_start_stop.c
index 8dca4cd5..b3be9937 100644
--- a/src/testcurl/test_start_stop.c
+++ b/src/testcurl/test_start_stop.c
@@ -110,6 +110,10 @@ main (int argc, char *const *argv)
110 errorCount += testMultithreadedGet (MHD_USE_POLL); 110 errorCount += testMultithreadedGet (MHD_USE_POLL);
111 errorCount += testMultithreadedPoolGet (MHD_USE_POLL); 111 errorCount += testMultithreadedPoolGet (MHD_USE_POLL);
112#endif 112#endif
113#if EPOLL_SUPPORT
114 errorCount += testInternalGet (MHD_USE_EPOLL_LINUX_ONLY);
115 errorCount += testMultithreadedPoolGet (MHD_USE_EPOLL_LINUX_ONLY);
116#endif
113 if (errorCount != 0) 117 if (errorCount != 0)
114 fprintf (stderr, "Error (code: %u)\n", errorCount); 118 fprintf (stderr, "Error (code: %u)\n", errorCount);
115 return errorCount != 0; /* 0 == pass */ 119 return errorCount != 0; /* 0 == pass */