commit 3bc4813f5232d5d36b3e813fde5139eefc22ac68
parent bb8f952bef2c17da6518f5da60eb8ffff3dd3751
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Thu, 27 Mar 2014 13:49:19 +0000
Increased FD_SETSIZE for W32, added MHD_get_fdset2
Diffstat:
3 files changed, 123 insertions(+), 19 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+Thu Mar 27 14:47:54 CET 2014
+ Used larger FD_SETSIZE internally on W32.
+ Extended API to work with non-default FD_SETSIZE. -EG
+
Tue Mar 25 12:53:55 CET 2014
Fix limiting by IPv6 address. -EG
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -1439,7 +1439,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
* Obtain the `select()` sets for this daemon.
* Daemon's FDs will be added to fd_sets. To get only
* daemon FDs in fd_sets, call FD_ZERO for each fd_set
- * before calling this function.
+ * before calling this function. FD_SETSIZE is assumed
+ * to be platform's default.
*
* @param daemon daemon to get sets from
* @param read_fd_set read set
@@ -1449,7 +1450,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
* than existing value); can be NULL
* @return #MHD_YES on success, #MHD_NO if this
* daemon was not started with the right
- * options for this call.
+ * options for this call or any FD didn't
+ * fit fd_set.
* @ingroup event
*/
_MHD_EXTERN int
@@ -1461,6 +1463,59 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
/**
+ * Obtain the `select()` sets for this daemon.
+ * Daemon's FDs will be added to fd_sets. To get only
+ * daemon FDs in fd_sets, call FD_ZERO for each fd_set
+ * before calling this function. Passing custom FD_SETSIZE
+ * as @a fd_setsize allow usage of larger/smaller than
+ * platform's default fd_sets.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or any FD didn't
+ * fit fd_set.
+ * @ingroup event
+ */
+_MHD_EXTERN int
+MHD_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize);
+
+
+/**
+ * Obtain the `select()` sets for this daemon.
+ * Daemon's FDs will be added to fd_sets. To get only
+ * daemon FDs in fd_sets, call FD_ZERO for each fd_set
+ * before calling this function. Size of fd_set is
+ * determined by current value of FD_SETSIZE.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or any FD didn't
+ * fit fd_set.
+ * @ingroup event
+ */
+#define MHD_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set,max_fd) \
+ MHD_get_fdset2((daemon),(read_fd_set),(write_fd_set),(except_fd_set),(max_fd),FD_SETSIZE)
+
+
+/**
* Obtain timeout value for `select()` for this daemon (only needed if
* connection timeout is used). The returned value is how long
* `select()` or `poll()` should at most block, not the timeout value set
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -24,6 +24,13 @@
* @author Daniel Pittman
* @author Christian Grothoff
*/
+#if defined(_WIN32) && !defined(__CYGWIN__)
+/* override small default value */
+#define FD_SETSIZE 1024
+#define MHD_DEFAULT_FD_SETSIZE 64
+#else
+#define MHD_DEFAULT_FD_SETSIZE FD_SETSIZE
+#endif
#include "platform.h"
#include "internal.h"
#include "response.h"
@@ -572,17 +579,19 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
* @param fd file descriptor to add to the @a set
* @param set set to modify
* @param max_fd maximum value to potentially update
+ * @param fd_setsize value of FD_SETSIZE
* @return #MHD_YES on success, #MHD_NO otherwise
*/
static int
add_to_fd_set (MHD_socket fd,
fd_set *set,
- MHD_socket *max_fd)
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
{
if (NULL == set)
return MHD_NO;
#ifdef MHD_WINSOCK_SOCKETS
- if (set->fd_count >= FD_SETSIZE)
+ if (set->fd_count >= fd_setsize)
{
if (FD_ISSET(fd, set))
return MHD_YES;
@@ -590,7 +599,7 @@ add_to_fd_set (MHD_socket fd,
return MHD_NO;
}
#else // ! MHD_WINSOCK_SOCKETS
- if (fd >= FD_SETSIZE)
+ if (fd >= fd_setsize)
return MHD_NO;
#endif // ! MHD_WINSOCK_SOCKETS
FD_SET (fd, set);
@@ -601,12 +610,14 @@ add_to_fd_set (MHD_socket fd,
return MHD_YES;
}
+#undef MHD_get_fdset
/**
* Obtain the `select()` sets for this daemon.
* Daemon's FDs will be added to fd_sets. To get only
* daemon FDs in fd_sets, call FD_ZERO for each fd_set
- * before calling this function.
+ * before calling this function. FD_SETSIZE is assumed
+ * to be platform's default.
*
* @param daemon daemon to get sets from
* @param read_fd_set read set
@@ -627,6 +638,40 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
fd_set *except_fd_set,
MHD_socket *max_fd)
{
+ return MHD_get_fdset2(daemon, read_fd_set,
+ write_fd_set, except_fd_set,
+ max_fd, MHD_DEFAULT_FD_SETSIZE);
+}
+
+/**
+ * Obtain the `select()` sets for this daemon.
+ * Daemon's FDs will be added to fd_sets. To get only
+ * daemon FDs in fd_sets, call FD_ZERO for each fd_set
+ * before calling this function. Passing custom FD_SETSIZE
+ * as @a fd_setsize allow usage of larger/smaller than
+ * platform's default fd_sets.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or any FD didn't
+ * fit fd_set.
+ * @ingroup event
+ */
+int
+MHD_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+{
struct MHD_Connection *pos;
if ( (NULL == daemon)
@@ -643,11 +688,11 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
/* we're in epoll mode, use the epoll FD as a stand-in for
the entire event set */
- return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd);
+ return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize);
}
#endif
if (MHD_INVALID_SOCKET != daemon->socket_fd &&
- MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd))
+ MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd, fd_setsize))
return MHD_NO;
for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
@@ -655,19 +700,19 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
switch (pos->event_loop_info)
{
case MHD_EVENT_LOOP_INFO_READ:
- if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+ if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
return MHD_NO;
break;
case MHD_EVENT_LOOP_INFO_WRITE:
- if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd))
+ if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd, fd_setsize))
return MHD_NO;
if (pos->read_buffer_size > pos->read_buffer_offset &&
- MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+ MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
return MHD_NO;
break;
case MHD_EVENT_LOOP_INFO_BLOCK:
if (pos->read_buffer_size > pos->read_buffer_offset &&
- MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+ MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
return MHD_NO;
break;
case MHD_EVENT_LOOP_INFO_CLEANUP:
@@ -742,19 +787,19 @@ MHD_handle_connection (void *data)
switch (con->event_loop_info)
{
case MHD_EVENT_LOOP_INFO_READ:
- if (MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+ if (MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
err_state = 1;
break;
case MHD_EVENT_LOOP_INFO_WRITE:
- if (MHD_YES != add_to_fd_set (con->socket_fd, &ws, &max))
+ if (MHD_YES != add_to_fd_set (con->socket_fd, &ws, &max, FD_SETSIZE))
err_state = 1;
if (con->read_buffer_size > con->read_buffer_offset &&
- MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+ MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
err_state = 1;
break;
case MHD_EVENT_LOOP_INFO_BLOCK:
if (con->read_buffer_size > con->read_buffer_offset &&
- MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+ MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
err_state = 1;
tv.tv_sec = 0;
tv.tv_usec = 0;
@@ -2091,7 +2136,7 @@ MHD_select (struct MHD_Daemon *daemon,
resume_suspended_connections (daemon);
/* single-threaded, go over everything */
- if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
+ if (MHD_NO == MHD_get_fdset2 (daemon, &rs, &ws, &es, &max, FD_SETSIZE))
return MHD_NO;
/* If we're at the connection limit, no need to
@@ -2104,11 +2149,11 @@ MHD_select (struct MHD_Daemon *daemon,
{
/* accept only, have one thread per connection */
if (MHD_INVALID_SOCKET != daemon->socket_fd &&
- MHD_YES != add_to_fd_set(daemon->socket_fd, &rs, &max))
+ MHD_YES != add_to_fd_set(daemon->socket_fd, &rs, &max, FD_SETSIZE))
return MHD_NO;
}
if (MHD_INVALID_PIPE_ != daemon->wpipe[0] &&
- MHD_YES != add_to_fd_set(daemon->wpipe[0], &rs, &max))
+ MHD_YES != add_to_fd_set(daemon->wpipe[0], &rs, &max, FD_SETSIZE))
return MHD_NO;
tv = NULL;