gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] 07/07: Added new function MHD_run_from_select2() with FD


From: gnunet
Subject: [libmicrohttpd] 07/07: Added new function MHD_run_from_select2() with FD_SETSIZE value
Date: Wed, 08 Nov 2023 18:23:09 +0100

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 32eae456fddba5b48d08f44dda956a0ea1ffffea
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Wed Nov 8 17:58:04 2023 +0300

    Added new function MHD_run_from_select2() with FD_SETSIZE value
    
    Added wrapper macro MHD_run_from_select() to automatically use current
    FD_SETSIZE value.
    This should complete the support for flexible FD_SETSIZE (which is used
    on most platforms with GNU/Linux as notable exception).
    This also fixes potential fd_set overrun when sockets with too large
    numbers are used.
---
 src/include/microhttpd.h     |  72 ++++++++++
 src/microhttpd/daemon.c      | 323 ++++++++++++++++++++++++++++++++++---------
 src/microhttpd/mhd_sockets.c |   2 +-
 src/microhttpd/mhd_sockets.h |   2 +-
 4 files changed, 328 insertions(+), 71 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 221d24fc..9e7e23e2 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -3387,6 +3387,78 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
                      const fd_set *except_fd_set);
 
 
+/**
+ * Run webserver operations. This method should be called by clients
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
+ * This function specifies FD_SETSIZE used when provided fd_sets were
+ * created. It is important on platforms where FD_SETSIZE can be
+ * overridden.
+ *
+ * You can use this function instead of #MHD_run if you called
+ * 'select()' on the result from #MHD_get_fdset2().  File descriptors in
+ * the sets that are not controlled by MHD will be ignored.  Calling
+ * this function instead of #MHD_run() is more efficient as MHD will
+ * not have to call 'select()' again to determine which operations are
+ * ready.
+ *
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be
+ * called right after 'select()' returns regardless of detected activity
+ * on the daemon's FDs.
+ *
+ * This function cannot be used with daemon started with
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon the daemon to run select loop for
+ * @param read_fd_set the read set
+ * @param write_fd_set the write set
+ * @param except_fd_set the except set
+ * @param fd_setsize the value of FD_SETSIZE
+ * @return #MHD_NO on serious errors, #MHD_YES on success
+ * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_run_from_select2 (struct MHD_Daemon *daemon,
+                      const fd_set *read_fd_set,
+                      const fd_set *write_fd_set,
+                      const fd_set *except_fd_set,
+                      unsigned int fd_setsize);
+
+
+/**
+ * Run webserver operations. This method should be called by clients
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
+ * This macro automatically substitutes current FD_SETSIZE value.
+ * It is important on platforms where FD_SETSIZE can be overridden.
+ *
+ * You can use this function instead of #MHD_run if you called
+ * 'select()' on the result from #MHD_get_fdset2().  File descriptors in
+ * the sets that are not controlled by MHD will be ignored.  Calling
+ * this function instead of #MHD_run() is more efficient as MHD will
+ * not have to call 'select()' again to determine which operations are
+ * ready.
+ *
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be
+ * called right after 'select()' returns regardless of detected activity
+ * on the daemon's FDs.
+ *
+ * This function cannot be used with daemon started with
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon the daemon to run select loop for
+ * @param read_fd_set the read set
+ * @param write_fd_set the write set
+ * @param except_fd_set the except set
+ * @param fd_setsize the value of FD_SETSIZE
+ * @return #MHD_NO on serious errors, #MHD_YES on success
+ * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE
+ * @ingroup event
+ */
+#define MHD_run_from_select(d,r,w,e) \
+  MHD_run_from_select2((d),(r),(w),(e),(unsigned int)(FD_SETSIZE))
+
 /* **************** Connection handling functions ***************** */
 
 /**
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 2489728f..d8151bea 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -726,7 +726,7 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
               fd_set *ws,
               fd_set *es,
               MHD_socket *max_fd,
-              unsigned int fd_setsize)
+              int fd_setsize)
 {
   const MHD_socket conn_sckt = urh->connection->socket_fd;
   const MHD_socket mhd_sckt = urh->mhd.socket;
@@ -799,12 +799,14 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
  * @param rs read result from select()
  * @param ws write result from select()
  * @param es except result from select()
+ * @param fd_setsize value of FD_SETSIZE used when fd_sets were created
  */
 static void
 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
                 const fd_set *rs,
                 const fd_set *ws,
-                const fd_set *es)
+                const fd_set *es,
+                int fd_setsize)
 {
   const MHD_socket conn_sckt = urh->connection->socket_fd;
   const MHD_socket mhd_sckt = urh->mhd.socket;
@@ -815,25 +817,49 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
   urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY)
                     & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY));
 
+  mhd_assert (urh->connection->sk_nonblck);
+
+#ifndef HAS_FD_SETSIZE_OVERRIDABLE
+  (void) fd_setsize; /* Mute compiler warning */
+  mhd_assert (((int) FD_SETSIZE) <= fd_setsize);
+  fd_setsize = FD_SETSIZE; /* Help compiler to optimise */
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+
   if (MHD_INVALID_SOCKET != conn_sckt)
   {
-    if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
+    if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (conn_sckt, NULL, fd_setsize))
+    {
+      if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
+        urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+      if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
+        urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+      if ((NULL != es) &&
+          FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es)))
+        urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+    }
+    else
+    { /* Cannot check readiness. Force ready state is safe as socket is 
non-blocking */
       urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
-    if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
       urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
-    if ((NULL != es) &&
-        FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es)))
-      urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+    }
   }
   if ((MHD_INVALID_SOCKET != mhd_sckt))
   {
-    if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
+    if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (mhd_sckt, NULL, fd_setsize))
+    {
+      if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
+        urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+      if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
+        urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+      if ((NULL != es) &&
+          FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es)))
+        urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+    }
+    else
+    { /* Cannot check readiness. Force ready state is safe as socket is 
non-blocking */
       urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
-    if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
       urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
-    if ((NULL != es) &&
-        FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es)))
-      urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+    }
   }
 }
 
@@ -958,7 +984,7 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
                      fd_set *write_fd_set,
                      fd_set *except_fd_set,
                      MHD_socket *max_fd,
-                     unsigned int fd_setsize)
+                     int fd_setsize)
 {
   struct MHD_Connection *pos;
   struct MHD_Connection *posn;
@@ -1186,7 +1212,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
     return MHD_add_to_fd_set_ (daemon->epoll_fd,
                                read_fd_set,
                                max_fd,
-                               fd_setsize) ? MHD_YES : MHD_NO;
+                               (int) fd_setsize) ? MHD_YES : MHD_NO;
   }
 #endif
 
@@ -1195,7 +1221,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                               write_fd_set,
                               except_fd_set,
                               max_fd,
-                              fd_setsize);
+                              (int) fd_setsize);
 }
 
 
@@ -1806,7 +1832,8 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
       urh_from_fdset (urh,
                       &rs,
                       &ws,
-                      &es);
+                      &es,
+                      (int) FD_SETSIZE);
       process_urh (urh);
     }
   }
@@ -4372,7 +4399,8 @@ get_timeout_millisec_int (struct MHD_Daemon *daemon,
  * @param daemon daemon to run select loop for
  * @param read_fd_set read set
  * @param write_fd_set write set
- * @param except_fd_set except set (not used, can be NULL)
+ * @param except_fd_set except set
+ * @param fd_setsize value of FD_SETSIZE used when fd_sets were created
  * @return #MHD_NO on serious errors, #MHD_YES on success
  * @ingroup event
  */
@@ -4380,26 +4408,14 @@ static enum MHD_Result
 internal_run_from_select (struct MHD_Daemon *daemon,
                           const fd_set *read_fd_set,
                           const fd_set *write_fd_set,
-                          const fd_set *except_fd_set)
+                          const fd_set *except_fd_set,
+                          int fd_setsize)
 {
   MHD_socket ds;
-  struct MHD_Connection *pos;
-  struct MHD_Connection *prev;
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   struct MHD_UpgradeResponseHandle *urh;
   struct MHD_UpgradeResponseHandle *urhn;
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-  /* Reset. New value will be set when connections are processed. */
-  /* Note: no-op for thread-per-connection as it is always false in that mode. 
*/
-  daemon->data_already_pending = false;
-
-  /* Clear ITC to avoid spinning select */
-  /* Do it before any other processing so new signals
-     will trigger select again and will be processed */
-  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
-       (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
-                  (fd_set *) _MHD_DROP_CONST (read_fd_set))) )
-    MHD_itc_clear_ (daemon->itc);
 
   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
               (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
@@ -4408,36 +4424,86 @@ internal_run_from_select (struct MHD_Daemon *daemon,
   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
 
+  mhd_assert (0 < fd_setsize);
+#ifndef HAS_FD_SETSIZE_OVERRIDABLE
+  (void) fd_setsize; /* Mute compiler warning */
+  mhd_assert (((int) FD_SETSIZE) <= fd_setsize);
+  fd_setsize = FD_SETSIZE; /* Help compiler to optimise */
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+
+  /* Clear ITC to avoid spinning select */
+  /* Do it before any other processing so new signals
+     will trigger select again and will be processed */
+  if (MHD_ITC_IS_VALID_ (daemon->itc))
+  { /* Have ITC */
+    bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe 
to clear even if ITC not activated */
+    if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc),
+                                         NULL, fd_setsize))
+      need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \
+                                    (fd_set *) _MHD_DROP_CONST (read_fd_set)); 
/* Skip clearing, if not needed */
+    if (need_to_clear_itc)
+      MHD_itc_clear_ (daemon->itc);
+  }
+
+  /* Reset. New value will be set when connections are processed. */
+  /* Note: no-op for thread-per-connection as it is always false in that mode. 
*/
+  daemon->data_already_pending = false;
+
   /* Process externally added connection if any */
   if (daemon->have_new)
     new_connections_list_process_ (daemon);
 
   /* select connection thread handling type */
-  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
-       (! daemon->was_quiesced) &&
-       (FD_ISSET (ds,
-                  (fd_set *) _MHD_DROP_CONST (read_fd_set))) )
-    (void) MHD_accept_connection (daemon);
+  ds = daemon->listen_fd;
+  if ( (MHD_INVALID_SOCKET != ds) &&
+       (! daemon->was_quiesced) )
+  {
+    bool need_to_accept;
+    if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize))
+      need_to_accept = FD_ISSET (ds,
+                                 (fd_set *) _MHD_DROP_CONST (read_fd_set));
+    else                                       /* Cannot check whether new 
connection are pending */
+      need_to_accept = daemon->listen_nonblk;  /* Try to accept if 
non-blocking */
 
-  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+    if (need_to_accept)
+      (void) MHD_accept_connection (daemon);
+  }
+
+  if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   {
     /* do not have a thread per connection, process all connections now */
-    prev = daemon->connections_tail;
-    while (NULL != (pos = prev))
+    struct MHD_Connection *pos;
+    for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
     {
-      prev = pos->prev;
-      ds = pos->socket_fd;
-      if (MHD_INVALID_SOCKET == ds)
+      MHD_socket cs;
+      bool r_ready;
+      bool w_ready;
+      bool has_err;
+
+      cs = pos->socket_fd;
+      if (MHD_INVALID_SOCKET == cs)
         continue;
+
+      if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize))
+      {
+        r_ready = FD_ISSET (cs,
+                            (fd_set *) _MHD_DROP_CONST (read_fd_set));
+        w_ready = FD_ISSET (cs,
+                            (fd_set *) _MHD_DROP_CONST (write_fd_set));
+        has_err = (NULL != except_fd_set) &&
+                  FD_ISSET (cs,
+                            (fd_set *) _MHD_DROP_CONST (except_fd_set));
+      }
+      else
+      { /* Cannot check the real readiness */
+        r_ready = pos->sk_nonblck;
+        w_ready = r_ready;
+        has_err = false;
+      }
       call_handlers (pos,
-                     FD_ISSET (ds,
-                               (fd_set *) _MHD_DROP_CONST (read_fd_set)),
-                     FD_ISSET (ds,
-                               (fd_set *) _MHD_DROP_CONST (write_fd_set)),
-                     (NULL != except_fd_set) ?
-                     (FD_ISSET (ds,
-                                (fd_set *) _MHD_DROP_CONST (except_fd_set))) :
-                     (false));
+                     r_ready,
+                     w_ready,
+                     has_err);
     }
   }
 
@@ -4450,7 +4516,8 @@ internal_run_from_select (struct MHD_Daemon *daemon,
     urh_from_fdset (urh,
                     read_fd_set,
                     write_fd_set,
-                    except_fd_set);
+                    except_fd_set,
+                    fd_setsize);
     /* call generic forwarding function for passing data */
     process_urh (urh);
     /* Finished forwarding? */
@@ -4471,37 +4538,45 @@ internal_run_from_select (struct MHD_Daemon *daemon,
 }
 
 
+#undef MHD_run_from_select
+
 /**
  * Run webserver operations. This method should be called by clients
  * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
  * client-controlled select method is used.
+ * This function specifies FD_SETSIZE used when provided fd_sets were
+ * created. It is important on platforms where FD_SETSIZE can be
+ * overridden.
  *
  * You can use this function instead of #MHD_run if you called
- * `select()` on the result from #MHD_get_fdset.  File descriptors in
+ * 'select()' on the result from #MHD_get_fdset2().  File descriptors in
  * the sets that are not controlled by MHD will be ignored.  Calling
- * this function instead of #MHD_run is more efficient as MHD will
- * not have to call `select()` again to determine which operations are
+ * this function instead of #MHD_run() is more efficient as MHD will
+ * not have to call 'select()' again to determine which operations are
  * ready.
  *
  * If #MHD_get_timeout() returned #MHD_YES, than this function must be
- * called right after `select()` returns regardless of detected activity
+ * called right after 'select()' returns regardless of detected activity
  * on the daemon's FDs.
  *
  * This function cannot be used with daemon started with
  * #MHD_USE_INTERNAL_POLLING_THREAD flag.
  *
- * @param daemon daemon to run select loop for
- * @param read_fd_set read set
- * @param write_fd_set write set
- * @param except_fd_set except set
+ * @param daemon the daemon to run select loop for
+ * @param read_fd_set the read set
+ * @param write_fd_set the write set
+ * @param except_fd_set the except set
+ * @param fd_setsize the value of FD_SETSIZE
  * @return #MHD_NO on serious errors, #MHD_YES on success
+ * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE
  * @ingroup event
  */
 _MHD_EXTERN enum MHD_Result
-MHD_run_from_select (struct MHD_Daemon *daemon,
-                     const fd_set *read_fd_set,
-                     const fd_set *write_fd_set,
-                     const fd_set *except_fd_set)
+MHD_run_from_select2 (struct MHD_Daemon *daemon,
+                      const fd_set *read_fd_set,
+                      const fd_set *write_fd_set,
+                      const fd_set *except_fd_set,
+                      unsigned int fd_setsize)
 {
   if (MHD_D_IS_USING_POLL_ (daemon) ||
       (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)))
@@ -4516,6 +4591,49 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
                  "set to NULL. Such behavior is deprecated.\n"));
   }
 #endif /* HAVE_MESSAGES */
+
+#ifdef HAS_FD_SETSIZE_OVERRIDABLE
+  if (0 == fd_setsize)
+    return MHD_NO;
+  else if (((unsigned int) INT_MAX) < fd_setsize)
+    fd_setsize = (unsigned int) INT_MAX;
+#ifdef HAVE_MESSAGES
+  else if (daemon->fdset_size > ((int) fd_setsize))
+  {
+    if (daemon->fdset_size_set_by_app)
+    {
+      MHD_DLOG (daemon,
+                _ ("%s() called with fd_setsize (%u) " \
+                   "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \
+                   "Some socket FDs may be not processed. " \
+                   "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"),
+                "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
+    }
+    else
+    {
+      MHD_DLOG (daemon,
+                _ ("%s() called with fd_setsize (%u) " \
+                   "less than FD_SETSIZE used by MHD (%d). " \
+                   "Some socket FDs may be not processed. " \
+                   "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"),
+                "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
+    }
+  }
+#endif /* HAVE_MESSAGES */
+#else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+  if (((unsigned int) FD_SETSIZE) > fd_setsize)
+  {
+#ifdef HAVE_MESSAGES
+    MHD_DLOG (daemon,
+              _ ("%s() called with fd_setsize (%u) " \
+                 "less than fixed FD_SETSIZE value (%d) used on the " \
+                 "platform.\n", "MHD_run_from_select2"),
+              fd_setsize, (int) FD_SETSIZE);
+#endif /* HAVE_MESSAGES */
+    return MHD_NO;
+  }
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+
   if (MHD_D_IS_USING_EPOLL_ (daemon))
   {
 #ifdef EPOLL_SUPPORT
@@ -4536,7 +4654,55 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
   return internal_run_from_select (daemon,
                                    read_fd_set,
                                    write_fd_set,
-                                   except_fd_set);
+                                   except_fd_set,
+                                   (int) fd_setsize);
+}
+
+
+/**
+ * Run webserver operations. This method should be called by clients
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
+ *
+ * You can use this function instead of #MHD_run if you called
+ * `select()` on the result from #MHD_get_fdset.  File descriptors in
+ * the sets that are not controlled by MHD will be ignored.  Calling
+ * this function instead of #MHD_run is more efficient as MHD will
+ * not have to call `select()` again to determine which operations are
+ * ready.
+ *
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be
+ * called right after `select()` returns regardless of detected activity
+ * on the daemon's FDs.
+ *
+ * This function cannot be used with daemon started with
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to run select loop for
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @return #MHD_NO on serious errors, #MHD_YES on success
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_run_from_select (struct MHD_Daemon *daemon,
+                     const fd_set *read_fd_set,
+                     const fd_set *write_fd_set,
+                     const fd_set *except_fd_set)
+{
+  return MHD_run_from_select2 (daemon,
+                               read_fd_set,
+                               write_fd_set,
+                               except_fd_set,
+#ifdef HAS_FD_SETSIZE_OVERRIDABLE
+                               daemon->fdset_size_set_by_app ?
+                               ((unsigned int) daemon->fdset_size) :
+                               ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
+#else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+                               ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
+#endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
+                               );
 }
 
 
@@ -4587,7 +4753,7 @@ MHD_select (struct MHD_Daemon *daemon,
                              &ws,
                              &es,
                              &maxsock,
-                             FD_SETSIZE))
+                             (int) FD_SETSIZE))
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -4604,7 +4770,7 @@ MHD_select (struct MHD_Daemon *daemon,
          (! MHD_add_to_fd_set_ (ls,
                                 &rs,
                                 &maxsock,
-                                FD_SETSIZE)) )
+                                (int) FD_SETSIZE)) )
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -4617,7 +4783,7 @@ MHD_select (struct MHD_Daemon *daemon,
        (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
                               &rs,
                               &maxsock,
-                              FD_SETSIZE)) )
+                              (int) FD_SETSIZE)) )
   {
     bool retry_succeed;
 
@@ -4634,7 +4800,7 @@ MHD_select (struct MHD_Daemon *daemon,
       if (MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
                               &rs,
                               &maxsock,
-                              FD_SETSIZE))
+                              (int) FD_SETSIZE))
         retry_succeed = true;
     }
 #endif /* MHD_WINSOCK_SOCKETS */
@@ -4731,7 +4897,8 @@ MHD_select (struct MHD_Daemon *daemon,
   if (MHD_NO != internal_run_from_select (daemon,
                                           &rs,
                                           &ws,
-                                          &es))
+                                          &es,
+                                          (int) FD_SETSIZE))
     return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
   return MHD_NO;
 }
@@ -5675,6 +5842,24 @@ MHD_run_wait (struct MHD_Daemon *daemon,
 #endif
   if (1)
   {
+    mhd_assert (MHD_D_IS_USING_SELECT_ (daemon));
+#ifdef HAS_FD_SETSIZE_OVERRIDABLE
+#ifdef HAVE_MESSAGES
+    if (daemon->fdset_size_set_by_app
+        && (((int) FD_SETSIZE) < daemon->fdset_size))
+    {
+      MHD_DLOG (daemon,
+                _ ("MHD_run()/MHD_run_wait() called for daemon started with " \
+                   "MHD_OPTION_APP_FD_SETSIZE option (%d). " \
+                   "The library was compiled with smaller FD_SETSIZE (%d). " \
+                   "Some socket FDs may be not processed. " \
+                   "Use MHD_run_from_select2() instead of MHD_run() or " \
+                   "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"),
+                daemon->fdset_size, (int) FD_SETSIZE);
+    }
+#endif /* HAVE_MESSAGES */
+#endif /* HAS_FD_SETSIZE_OVERRIDABLE */
+
     res = MHD_select (daemon, millisec);
     /* MHD_select does MHD_cleanup_connections already */
   }
diff --git a/src/microhttpd/mhd_sockets.c b/src/microhttpd/mhd_sockets.c
index 2e49652c..bd7f30d3 100644
--- a/src/microhttpd/mhd_sockets.c
+++ b/src/microhttpd/mhd_sockets.c
@@ -381,7 +381,7 @@ int
 MHD_add_to_fd_set_ (MHD_socket fd,
                     fd_set *set,
                     MHD_socket *max_fd,
-                    unsigned int fd_setsize)
+                    int fd_setsize)
 {
   if ( (NULL == set) ||
        (MHD_INVALID_SOCKET == fd) )
diff --git a/src/microhttpd/mhd_sockets.h b/src/microhttpd/mhd_sockets.h
index 4e0e34d0..3b953c3f 100644
--- a/src/microhttpd/mhd_sockets.h
+++ b/src/microhttpd/mhd_sockets.h
@@ -881,7 +881,7 @@ int
 MHD_add_to_fd_set_ (MHD_socket fd,
                     fd_set *set,
                     MHD_socket *max_fd,
-                    unsigned int fd_setsize);
+                    int fd_setsize);
 
 
 /**

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]