gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [libmicrohttpd] branch master updated (dd3da902 -> 46a8b847


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated (dd3da902 -> 46a8b847)
Date: Wed, 01 Mar 2017 21:51:18 +0100

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from dd3da902 i18n example: re-add useful comments as suggested by Karlson2k
     new 8314b675 Watch sockets for out-of-band data in select() mode too. This 
even more unify select() and poll()/epoll modes.
     new cf9bb942 Watch "upgraded" sockets for OOB data and disconnects. 
Currently states are only monitored. States processing have to be added.
     new 46a8b847 Clarified comment

The 3 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/microhttpd/daemon.c   | 311 ++++++++++++++++++++++++++++++----------------
 src/microhttpd/response.c |   6 +-
 2 files changed, 205 insertions(+), 112 deletions(-)

diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 283c8c45..95239427 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -681,82 +681,179 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
  * @param urh upgrade handle to wait for
  * @param[out] rs read set to initialize
  * @param[out] ws write set to initialize
+ * @param[out] es except set to initialize
  * @param[out] max_fd maximum FD to update
  * @param fd_setsize value of FD_SETSIZE
- * @return #MHD_YES on success, #MHD_NO on error
+ * @return true on success, false on error
  */
-static int
+static bool
 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
               fd_set *rs,
               fd_set *ws,
+              fd_set *es,
               MHD_socket *max_fd,
               unsigned int fd_setsize)
 {
-  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
-       (MHD_INVALID_SOCKET != urh->mhd.socket) &&
-       (! MHD_add_to_fd_set_ (urh->mhd.socket,
-                              rs,
-                              max_fd,
-                              fd_setsize)) )
-    return MHD_NO;
-  if ( (0 != urh->in_buffer_used) &&
-       (! urh->was_closed) &&
-       (MHD_INVALID_SOCKET != urh->mhd.socket) &&
-       (! MHD_add_to_fd_set_ (urh->mhd.socket,
-                              ws,
-                              max_fd,
-                              fd_setsize)) )
-    return MHD_NO;
-  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
-       (! urh->was_closed) &&
-       (MHD_INVALID_SOCKET != urh->connection->socket_fd) &&
-       (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
-                              rs,
-                              max_fd,
-                              fd_setsize)) )
-    return MHD_NO;
-  if ( (0 != urh->out_buffer_used) &&
-       (MHD_INVALID_SOCKET != urh->connection->socket_fd) &&
-       (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
-                              ws,
-                              max_fd,
-                              fd_setsize)) )
-    return MHD_NO;
-  return MHD_YES;
+  const MHD_socket conn_sckt = urh->connection->socket_fd;
+  const MHD_socket mhd_sckt = urh->mhd.socket;
+  bool res = true;
+
+  if (MHD_INVALID_SOCKET != conn_sckt)
+    {
+      if ( (urh->in_buffer_used < urh->in_buffer_size) &&
+           (! MHD_add_to_fd_set_ (conn_sckt,
+                                  rs,
+                                  max_fd,
+                                  fd_setsize)) )
+        res = false;
+      if ( (0 != urh->out_buffer_used) &&
+           (! MHD_add_to_fd_set_ (conn_sckt,
+                                  ws,
+                                  max_fd,
+                                  fd_setsize)) )
+        res = false;
+      if (0 != urh->in_buffer_size)
+        MHD_add_to_fd_set_ (conn_sckt,
+                            es,
+                            max_fd,
+                            fd_setsize);
+    }
+  if (MHD_INVALID_SOCKET != mhd_sckt)
+    {
+      if ( (urh->out_buffer_used < urh->out_buffer_size) &&
+           (! MHD_add_to_fd_set_ (mhd_sckt,
+                                  rs,
+                                  max_fd,
+                                  fd_setsize)) )
+        res = false;
+      if ( (0 != urh->in_buffer_used) &&
+           (! MHD_add_to_fd_set_ (mhd_sckt,
+                                  ws,
+                                  max_fd,
+                                  fd_setsize)) )
+        res = false;
+      if (0 != urh->out_buffer_size)
+        MHD_add_to_fd_set_ (mhd_sckt,
+                            es,
+                            max_fd,
+                            fd_setsize);
+    }
+
+  return res;
 }
 
 
 /**
- * Update the @a urh based on the ready FDs in the @a rs and @a ws.
+ * Update the @a urh based on the ready FDs in
+ * the @a rs, @a ws, and @a es.
  *
  * @param urh upgrade handle to update
  * @param rs read result from select()
  * @param ws write result from select()
+ * @param ws except result from select()
  */
 static void
 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
                 const fd_set *rs,
-                const fd_set *ws)
+                const fd_set *ws,
+                const fd_set *es,)
 {
-  const MHD_socket mhd_sckt = urh->mhd.socket;
   const MHD_socket conn_sckt = urh->connection->socket_fd;
+  const MHD_socket mhd_sckt = urh->mhd.socket;
+
+  urh->app.celi = MHD_EPOLL_STATE_UNREADY;
+  urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
+
+  if (MHD_INVALID_SOCKET != conn_sckt)
+    {
+      if (FD_ISSET (conn_sckt, rs))
+        urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+      if (FD_ISSET (conn_sckt, ws))
+        urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+      if (FD_ISSET (conn_sckt, es))
+        urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+    }
+  if ((MHD_INVALID_SOCKET != mhd_sckt))
+    {
+      if (FD_ISSET (mhd_sckt, rs))
+        urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+      if (FD_ISSET (mhd_sckt, ws))
+        urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+      if (FD_ISSET (mhd_sckt, es))
+        urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+    }
+}
+
+
+/**
+ * Set required 'event' members in 'pollfd' elements,
+ * assuming that @a p[0].fd is MHD side of socketpair
+ * and @a p[1].fd is TLS connected socket.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to update
+ */
+static void
+urh_update_pollfd(struct MHD_UpgradeResponseHandle *urh,
+                  struct pollfd p[2])
+{
+  p[0].events = 0;
+  p[1].events = 0;
+  if (urh->in_buffer_used < urh->in_buffer_size)
+    p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+  if (0 != urh->out_buffer_used)
+    p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+  if (0 != urh->in_buffer_size)
+    p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
+  if (urh->out_buffer_used < urh->out_buffer_size)
+    p[1].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+  if (0 != urh->in_buffer_used)
+    p[1].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+  if (0 != urh->out_buffer_size)
+    p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
+}
+
 
-  if ((MHD_INVALID_SOCKET != conn_sckt) &&
-      FD_ISSET (conn_sckt, rs))
+/**
+ * Set @a p to watch for @a urh.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to set
+ */
+static void
+urh_to_pollfd(struct MHD_UpgradeResponseHandle *urh,
+              struct pollfd p[2])
+{
+  p[0].fd = urh->connection->socket_fd;
+  p[1].fd = urh->mhd.socket;
+  urh_update_pollfd(urh, p);
+}
+
+
+/**
+ * Update ready state in @a urh based on pollfd.
+ * @param urh upgrade handle to update
+ * @param p 'poll()' processed pollfd.
+ */
+static void
+urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh,
+                struct pollfd p[2])
+{
+  if (0 != (p[0].revents & POLLIN))
     urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
-  if ((MHD_INVALID_SOCKET != conn_sckt) &&
-      FD_ISSET (conn_sckt, ws))
+  if (0 != (p[0].revents & POLLOUT))
     urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
-  if ((MHD_INVALID_SOCKET != mhd_sckt) &&
-      FD_ISSET (mhd_sckt, rs))
+  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC))
+    urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+  if (0 != (p[1].revents & POLLIN))
     urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
-  if ((MHD_INVALID_SOCKET != mhd_sckt) &&
-      FD_ISSET (mhd_sckt, ws))
+  if (0 != (p[1].revents & POLLOUT))
     urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERR_DISC))
+    urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
 }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
 
-
 /**
  * Obtain the `select()` sets for this daemon.
  * Daemon's FDs will be added to fd_sets. To get only
@@ -819,6 +916,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                               fd_setsize)) )
     result = MHD_NO;
 
+  /* Add all sockets to 'except_fd_set' as well to watch for
+   * out-of-band data. However, ignore errors if INFO_READ
+   * or INFO_WRITE sockets will not fit 'except_fd_set'. */
   /* Start from oldest connections. Make sense for W32 FDSETs. */
   for (pos = daemon->connections_tail; NULL != pos; pos = posn)
     {
@@ -832,6 +932,12 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                                     max_fd,
                                     fd_setsize))
            result = MHD_NO;
+#ifdef MHD_POSIX_SOCKETS
+          MHD_add_to_fd_set_ (pos->socket_fd,
+                              except_fd_set,
+                              max_fd,
+                              fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
          break;
        case MHD_EVENT_LOOP_INFO_WRITE:
          if (! MHD_add_to_fd_set_ (pos->socket_fd,
@@ -839,6 +945,12 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                                     max_fd,
                                     fd_setsize))
            result = MHD_NO;
+#ifdef MHD_POSIX_SOCKETS
+          MHD_add_to_fd_set_ (pos->socket_fd,
+                              except_fd_set,
+                              max_fd,
+                              fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
          break;
        case MHD_EVENT_LOOP_INFO_BLOCK:
          if ( (NULL == except_fd_set) ||
@@ -853,6 +965,19 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
          break;
        }
     }
+#ifdef MHD_WINSOCK_SOCKETS
+  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
+   * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
+   * not be pushed out. */
+  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
+    {
+      posn = pos->prev;
+      MHD_add_to_fd_set_ (pos->socket_fd,
+                          except_fd_set,
+                          max_fd,
+                          fd_setsize);
+    }
+#endif /* MHD_WINSOCK_SOCKETS */
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   {
     struct MHD_UpgradeResponseHandle *urh;
@@ -863,6 +988,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
             urh_to_fdset (urh,
                           read_fd_set,
                           write_fd_set,
+                          except_fd_set,
                           max_fd,
                           fd_setsize))
           result = MHD_NO;
@@ -1334,19 +1460,22 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
           /* use select */
           fd_set rs;
           fd_set ws;
+          fd_set es;
           MHD_socket max_fd;
           int num_ready;
-          int result;
+          bool result;
 
           FD_ZERO (&rs);
           FD_ZERO (&ws);
+          FD_ZERO (&es);
           max_fd = MHD_INVALID_SOCKET;
           result = urh_to_fdset (urh,
                                  &rs,
                                  &ws,
+                                 &es,
                                  &max_fd,
                                  FD_SETSIZE);
-          if (MHD_NO == result)
+          if (! result)
             {
 #ifdef HAVE_MESSAGES
               MHD_DLOG (con->daemon,
@@ -1371,7 +1500,7 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
               num_ready = MHD_SYS_select_ (max_fd + 1,
                                            &rs,
                                            &ws,
-                                           NULL,
+                                           &es,
                                            tvp);
             }
           else
@@ -1392,7 +1521,8 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
             }
           urh_from_fdset (urh,
                           &rs,
-                          &ws);
+                          &ws
+                          &es);
           process_urh (urh);
           if ( (0 == urh->in_buffer_size) &&
                (0 == urh->out_buffer_size) &&
@@ -1405,38 +1535,29 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
   else if (0 != (daemon->options & MHD_USE_TLS))
     {
       /* use poll() */
+      struct pollfd p[2];
+      memset (p,
+              0,
+              sizeof (p));
+      p[0].fd = urh->connection->socket_fd;
+      p[1].fd = urh->mhd.socket;
 
       while ( (MHD_CONNECTION_UPGRADE == con->state) ||
               (0 != urh->out_buffer_used) )
         {
-          struct pollfd p[2];
-          unsigned int timeout;
+          int timeout;
 
-          memset (p,
-                  0,
-                  sizeof (struct pollfd) * 2);
-          p[0].fd = urh->connection->socket_fd;
-          p[1].fd = urh->mhd.socket;
-          if (urh->in_buffer_used < urh->in_buffer_size)
-            p[0].events |= POLLIN;
-          if (0 != urh->out_buffer_used)
-            p[0].events |= POLLOUT;
-          if (urh->out_buffer_used < urh->out_buffer_size)
-            p[1].events |= POLLIN;
-          if (0 != urh->in_buffer_used)
-            p[1].events |= POLLOUT;
+          urh_update_pollfd(urh, p);
 
           if ( (con->tls_read_ready) &&
                (urh->in_buffer_used < urh->in_buffer_size))
             timeout = 0; /* No need to wait if incoming data is already 
pending in TLS buffers. */
           else
-            timeout = UINT_MAX;
+            timeout = -1;
 
-          /* FIXME: does this check really needed? */
-          if ( (0 != (p[0].events | p[1].events)) &&
-               (MHD_sys_poll_ (p,
-                               2,
-                               timeout) < 0) )
+          if (MHD_sys_poll_ (p,
+                             2,
+                             timeout) < 0)
             {
               const int err = MHD_socket_get_error_ ();
 
@@ -1449,14 +1570,7 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
 #endif
               break;
             }
-          if (0 != (p[0].revents & POLLIN))
-            urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
-          if (0 != (p[0].revents & POLLOUT))
-            urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
-          if (0 != (p[1].revents & POLLIN))
-            urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
-          if (0 != (p[1].revents & POLLOUT))
-            urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+          urh_from_pollfd(urh, p);
           process_urh (urh);
           if ( (0 == urh->in_buffer_size) &&
                (0 == urh->out_buffer_size) &&
@@ -3125,7 +3239,8 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
       /* update urh state based on select() output */
       urh_from_fdset (urh,
                       read_fd_set,
-                      write_fd_set);
+                      write_fd_set,
+                      except_fd_set);
       /* call generic forwarding function for passing data */
       process_urh (urh);
       /* Finished forwarding? */
@@ -3420,18 +3535,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
     for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
       {
-        p[poll_server+i].fd = urh->connection->socket_fd;
-        if (urh->in_buffer_used < urh->in_buffer_size)
-          p[poll_server+i].events |= POLLIN;
-        if (0 != urh->out_buffer_used)
-          p[poll_server+i].events |= POLLOUT;
-        i++;
-        p[poll_server+i].fd = urh->mhd.socket;
-        if (urh->out_buffer_used < urh->out_buffer_size)
-          p[poll_server+i].events |= POLLIN;
-        if (0 != urh->in_buffer_used)
-          p[poll_server+i].events |= POLLOUT;
-        i++;
+        urh_to_pollfd(urh, &(p[poll_server+i]));
+        i += 2;
       }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
     if (0 == poll_server + num_connections)
@@ -3500,23 +3605,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
          * from 'daemon->urh_head' list. */
         urhn = urh->prev;
         /* Check for fd mismatch. FIXME: required for safety? */
-        if (p[poll_server+i].fd == urh->connection->socket_fd)
-          {
-            if (0 != (p[poll_server+i].revents & POLLIN))
-              urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
-            if (0 != (p[poll_server+i].revents & POLLOUT))
-              urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
-          }
-        i++;
-        /* Check for fd mismatch. FIXME: required for safety? */
-        if (p[poll_server+i].fd == urh->mhd.socket)
-          {
-            if (0 != (p[poll_server+i].revents & POLLIN))
-              urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
-            if (0 != (p[poll_server+i].revents & POLLOUT))
-              urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
-          }
-        i++;
+        if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
+            (p[poll_server+i+1].fd != urh->mhd.socket))
+          break;
+        urh_from_pollfd(urh, &(p[poll_server+i]));
+        i += 2;
         process_urh (urh);
         /* Finished forwarding? */
         if ( (0 == urh->in_buffer_size) &&
@@ -3528,7 +3621,7 @@ MHD_poll_all (struct MHD_Daemon *daemon,
              * 'daemon->urh_head' list. */
             MHD_connection_finish_forward_ (urh->connection);
             urh->clean_ready = true;
-            /* If 'urh->was_closed' set to true, connection will be
+            /* If 'urh->was_closed' already was set to true, connection will be
              * moved immediately to cleanup list. Otherwise connection
              * will stay in suspended list until 'urh' will be marked
              * with 'was_closed' by application. */
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 498174e6..26ad649b 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -852,7 +852,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
 
         EXTRA_CHECK (-1 != daemon->epoll_upgrade_fd);
         /* First, add network socket */
-        event.events = EPOLLIN | EPOLLOUT;
+        event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
         event.data.ptr = &urh->app;
         if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
                             EPOLL_CTL_ADD,
@@ -871,14 +871,14 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
        }
 
         /* Second, add our end of the UNIX socketpair() */
-        event.events = EPOLLIN | EPOLLOUT;
+        event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
         event.data.ptr = &urh->mhd;
         if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
                             EPOLL_CTL_ADD,
                             urh->mhd.socket,
                             &event))
        {
-          event.events = EPOLLIN | EPOLLOUT;
+          event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
           event.data.ptr = &urh->app;
           if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
                               EPOLL_CTL_DEL,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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