gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated (9bdb6835 -> 32eae456)


From: gnunet
Subject: [libmicrohttpd] branch master updated (9bdb6835 -> 32eae456)
Date: Wed, 08 Nov 2023 18:23:02 +0100

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 9bdb6835 Used custom FD_SETSIZE in MHD_get_fdset2()
     new c66af735 daemon.c: cosmetics
     new ce1ca4cf MHD_run_from_select(): reworked workaround for missing 
except_fd_set
     new cec5aed9 mhd_itc.h: cosmetics
     new 8629a47f Upgraded connection: added missing check
     new dcb24300 Additional corrections for MHD_get_fdset2()
     new 09b7e335 Added ignore of MHD_OPTION_APP_FD_SETSIZE when poll() is used
     new 32eae456 Added new function MHD_run_from_select2() with FD_SETSIZE 
value

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/include/microhttpd.h     |  72 +++++++++
 src/microhttpd/daemon.c      | 359 +++++++++++++++++++++++++++++++++----------
 src/microhttpd/mhd_itc.h     |  93 +++++------
 src/microhttpd/mhd_sockets.c |   2 +-
 src/microhttpd/mhd_sockets.h |   2 +-
 src/microhttpd/response.c    |   9 ++
 6 files changed, 408 insertions(+), 129 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 037d87d2..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,23 +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 (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 (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es)))
-      urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+    }
   }
 }
 
@@ -956,8 +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;
@@ -1132,7 +1159,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
 #endif
 
 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
-  if (((unsigned int) INT_MAX) < fd_setsize)
+  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))
@@ -1140,20 +1169,20 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
     if (daemon->fdset_size_set_by_app)
     {
       MHD_DLOG (daemon,
-                _ ("MHD_get_fdset2() called with fd_setsize (%u) " \
+                _ ("%s() called with fd_setsize (%u) " \
                    "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \
-                   "Some socket FDs may be not added. " \
+                   "Some socket FDs may be not processed. " \
                    "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"),
-                fd_setsize, daemon->fdset_size);
+                "MHD_get_fdset2", fd_setsize, daemon->fdset_size);
     }
     else
     {
       MHD_DLOG (daemon,
-                _ ("MHD_get_fdset2() called with fd_setsize (%u) " \
+                _ ("%s() called with fd_setsize (%u) " \
                    "less than FD_SETSIZE used by MHD (%d). " \
-                   "Some socket FDs may be not added. " \
+                   "Some socket FDs may be not processed. " \
                    "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"),
-                fd_setsize, daemon->fdset_size);
+                "MHD_get_fdset2", fd_setsize, daemon->fdset_size);
     }
   }
 #endif /* HAVE_MESSAGES */
@@ -1162,10 +1191,10 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
   {
 #ifdef HAVE_MESSAGES
     MHD_DLOG (daemon,
-              _ ("MHD_get_fdset2() called with fd_setsize (%u) " \
+              _ ("%s() called with fd_setsize (%u) " \
                  "less than fixed FD_SETSIZE value (%d) used on the " \
                  "platform.\n"),
-              fd_setsize, (int) FD_SETSIZE);
+              "MHD_get_fdset2", fd_setsize, (int) FD_SETSIZE);
 #endif /* HAVE_MESSAGES */
     return MHD_NO;
   }
@@ -1183,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
 
@@ -1192,7 +1221,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                               write_fd_set,
                               except_fd_set,
                               max_fd,
-                              fd_setsize);
+                              (int) fd_setsize);
 }
 
 
@@ -1803,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);
     }
   }
@@ -4369,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
  */
@@ -4377,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)));
@@ -4405,34 +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)),
-                     FD_ISSET (ds,
-                               (fd_set *) _MHD_DROP_CONST (except_fd_set)));
+                     r_ready,
+                     w_ready,
+                     has_err);
     }
   }
 
@@ -4445,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? */
@@ -4466,54 +4538,102 @@ 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)
 {
-  fd_set es;
   if (MHD_D_IS_USING_POLL_ (daemon) ||
       (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)))
     return MHD_NO;
   if ((NULL == read_fd_set) || (NULL == write_fd_set))
     return MHD_NO;
-  if (NULL == except_fd_set)
-  {   /* Workaround to maintain backward compatibility. */
 #ifdef HAVE_MESSAGES
+  if (NULL == except_fd_set)
+  {
     MHD_DLOG (daemon,
               _ ("MHD_run_from_select() called with except_fd_set "
                  "set to NULL. Such behavior is deprecated.\n"));
-#endif
-    FD_ZERO (&es);
-    except_fd_set = &es;
   }
+#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
@@ -4534,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 */
+                               );
 }
 
 
@@ -4585,7 +4753,7 @@ MHD_select (struct MHD_Daemon *daemon,
                              &ws,
                              &es,
                              &maxsock,
-                             FD_SETSIZE))
+                             (int) FD_SETSIZE))
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -4602,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,
@@ -4615,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;
 
@@ -4632,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 */
@@ -4729,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;
 }
@@ -5673,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 */
   }
@@ -7184,6 +7371,16 @@ process_interim_params (struct MHD_Daemon *d,
                 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
                    "with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
 #endif /* HAVE_MESSAGES */
+      (void) 0;
+    }
+    else if (MHD_D_IS_USING_POLL_ (d))
+    {
+#ifdef HAVE_MESSAGES
+      MHD_DLOG (d,
+                _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
+                   "with MHD_USE_POLL.\n"));
+#endif /* HAVE_MESSAGES */
+      (void) 0;
     }
     else
     { /* The daemon without internal threads, external sockets polling */
diff --git a/src/microhttpd/mhd_itc.h b/src/microhttpd/mhd_itc.h
index 780a6c53..55f82664 100644
--- a/src/microhttpd/mhd_itc.h
+++ b/src/microhttpd/mhd_itc.h
@@ -42,10 +42,11 @@
 #    include <stdlib.h>
 #  endif /* HAVE_STDLIB_H */
 /* Simple implementation of MHD_PANIC, to be used outside lib */
-#  define MHD_PANIC(msg) do { fprintf (stderr,           \
-                                       "Abnormal termination at %d line in 
file %s: %s\n", \
-                                       (int) __LINE__, __FILE__, msg); abort 
(); \
-} while (0)
+#  define MHD_PANIC(msg)                                             \
+  do { fprintf (stderr,                                              \
+                "Abnormal termination at %d line in file %s: %s\n",  \
+                (int) __LINE__, __FILE__, msg); abort ();            \
+     } while (0)
 #endif /* ! MHD_PANIC */
 
 #if defined(_MHD_ITC_EVENTFD)
@@ -71,8 +72,8 @@
  * @param itc the itc to initialise
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
-                                                       | EFD_NONBLOCK)))
+#define MHD_itc_init_(itc) \
+  (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK)))
 
 /**
  * Get description string of last errno for itc operations.
@@ -90,9 +91,9 @@ static const uint64_t _MHD_itc_wr_data = 1;
  * @param str ignored
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_activate_(itc, str) \
-  ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
-                                                                  errno))
+#define MHD_itc_activate_(itc, str)                    \
+  ((write ((itc).fd, (const void*) &_MHD_itc_wr_data,  \
+           sizeof(_MHD_itc_wr_data)) > 0) || (EAGAIN == errno))
 
 /**
  * Return read FD of @a itc which can be used for poll(), select() etc.
@@ -112,9 +113,9 @@ static const uint64_t _MHD_itc_wr_data = 1;
  * Clear signaled state on @a itc
  * @param itc the itc to clear
  */
-#define MHD_itc_clear_(itc)                       \
-  do { uint64_t __b;                              \
-       (void) read ((itc).fd, &__b, sizeof(__b)); \
+#define MHD_itc_clear_(itc)                               \
+  do { uint64_t __b;                                      \
+       (void) read ((itc).fd, (void*)&__b, sizeof(__b));  \
      } while (0)
 
 /**
@@ -124,7 +125,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
  * @param itc the itc to destroy
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_destroy_(itc) ((0 == close ((itc).fd)) || (EBADF != errno))
+#define MHD_itc_destroy_(itc) \
+  ((0 == close ((itc).fd)) || (EBADF != errno))
 
 /**
  * Check whether ITC has valid value.
@@ -172,11 +174,11 @@ static const uint64_t _MHD_itc_wr_data = 1;
 #ifdef HAVE_PIPE2_FUNC
 #  define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
 #else  /* ! HAVE_PIPE2_FUNC */
-#  define MHD_itc_init_(itc)              \
-  ( (! pipe ((itc).fd)) ?                \
+#  define MHD_itc_init_(itc)          \
+  ( (! pipe ((itc).fd)) ?             \
     (MHD_itc_nonblocking_ ((itc)) ?   \
-     (! 0) :                         \
-     (MHD_itc_destroy_ ((itc)), 0) ) \
+     (! 0) :                          \
+     (MHD_itc_destroy_ ((itc)), 0) )  \
     : (0) )
 #endif /* ! HAVE_PIPE2_FUNC */
 
@@ -213,19 +215,19 @@ static const uint64_t _MHD_itc_wr_data = 1;
  * Clear signaled state on @a itc
  * @param itc the itc to clear
  */
-#define MHD_itc_clear_(itc) do                      \
-  { long __b;                                       \
-    while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
-    {} } while (0)
+#define MHD_itc_clear_(itc) do                                 \
+  { long __b;                                                  \
+    while (0 < read ((itc).fd[0], (void*) &__b, sizeof(__b)))  \
+    {(void)0;} } while (0)
 
 /**
  * Destroy previously initialised ITC
  * @param itc the itc to destroy
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_destroy_(itc)      \
-  ( (0 == close ((itc).fd[0])) ?   \
-    (0 == close ((itc).fd[1])) : \
+#define MHD_itc_destroy_(itc)     \
+  ( (0 == close ((itc).fd[0])) ?  \
+    (0 == close ((itc).fd[1])) :  \
     ((close ((itc).fd[1])), 0) )
 
 /**
@@ -278,11 +280,11 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc);
 #ifdef MHD_socket_pair_nblk_
 #  define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
 #else  /* ! MHD_socket_pair_nblk_ */
-#  define MHD_itc_init_(itc)            \
-  (MHD_socket_pair_ ((itc).sk) ?      \
+#  define MHD_itc_init_(itc)         \
+  (MHD_socket_pair_ ((itc).sk) ?     \
    (MHD_itc_nonblocking_ ((itc)) ?   \
-    (! 0) :                         \
-    (MHD_itc_destroy_ ((itc)), 0) ) \
+    (! 0) :                          \
+    (MHD_itc_destroy_ ((itc)), 0) )  \
    : (0))
 #endif /* ! MHD_socket_pair_nblk_ */
 
@@ -297,8 +299,8 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc);
  * @param str one-symbol string, useful only for strace debug
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_activate_(itc, str)          \
-  ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
+#define MHD_itc_activate_(itc, str)            \
+  ((MHD_send_ ((itc).sk[1], (str), 1) > 0) ||  \
    (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
 
 /**
@@ -319,21 +321,19 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc);
  * Clear signaled state on @a itc
  * @param itc the itc to clear
  */
-#define MHD_itc_clear_(itc) do      \
-  { long __b;                       \
-    while (0 < recv ((itc).sk[0],     \
-                     (char*) &__b,     \
-                     sizeof(__b), 0)) \
-    {} } while (0)
+#define MHD_itc_clear_(itc) do                                    \
+  { long __b;                                                     \
+    while (0 < recv ((itc).sk[0], (void*) &__b, sizeof(__b), 0))  \
+    {(void)0;} } while (0)
 
 /**
  * Destroy previously initialised ITC
  * @param itc the itc to destroy
  * @return non-zero if succeeded, zero otherwise
  */
-#define MHD_itc_destroy_(itc)          \
-  (MHD_socket_close_ ((itc).sk[0]) ?   \
-   MHD_socket_close_ ((itc).sk[1]) : \
+#define MHD_itc_destroy_(itc)         \
+  (MHD_socket_close_ ((itc).sk[0]) ?  \
+   MHD_socket_close_ ((itc).sk[1]) :  \
    ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
 
 
@@ -352,12 +352,13 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc);
  * Set @a itc to invalid value.
  * @param itc the itc to set
  */
-#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
-                                     MHD_INVALID_SOCKET)
+#define MHD_itc_set_invalid_(itc) \
+  ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET)
 
 #ifndef MHD_socket_pair_nblk_
-#  define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
-                                     MHD_socket_nonblocking_ ((pip).sk[1]))
+#  define MHD_itc_nonblocking_(pip)          \
+  (MHD_socket_nonblocking_ ((pip).sk[0]) &&  \
+   MHD_socket_nonblocking_ ((pip).sk[1]))
 #endif /* ! MHD_socket_pair_nblk_ */
 
 #endif /* _MHD_ITC_SOCKETPAIR */
@@ -367,9 +368,9 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc);
  * if error is detected.
  * @param itc the itc to destroy
  */
-#define MHD_itc_destroy_chk_(itc) do {          \
-    if (! MHD_itc_destroy_ (itc))                 \
-      MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
+#define MHD_itc_destroy_chk_(itc) do {             \
+    if (! MHD_itc_destroy_ (itc))                  \
+      MHD_PANIC (_ ("Failed to destroy ITC.\n"));  \
 } while (0)
 
 /**
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);
 
 
 /**
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index d592007d..78e874d0 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -1953,6 +1953,15 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
                                            MHD_STATICSTR_LEN_ ( \
                                              MHD_HTTP_HEADER_UPGRADE)));
 
+  if (! connection->sk_nonblck)
+  {
+#ifdef HAVE_MESSAGES
+    MHD_DLOG (daemon,
+              _ ("Cannot execute \"upgrade\" as the socket is in " \
+                 "the blocking mode.\n"));
+#endif
+    return MHD_NO;
+  }
   urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
   if (NULL == urh)
     return MHD_NO;

-- 
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]