gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [libmicrohttpd] GNU libmicrohttpd branch master updated. 51


From: gitolite
Subject: [GNUnet-SVN] [libmicrohttpd] GNU libmicrohttpd branch master updated. 51c1f5e65bff0eee79d87874ee5b8f1514c38032
Date: Thu, 10 Nov 2016 15:12:30 +0100 (CET)

The branch, master has been updated
       via  51c1f5e65bff0eee79d87874ee5b8f1514c38032 (commit)
       via  e05239e5c7c6d073fcc2500c59d3b1c39e44169d (commit)
       via  be045a04763cabf3c3416427499060a3bf68fd1e (commit)
      from  6d522346279df691b52a654dc1d1b815feae58e2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 51c1f5e65bff0eee79d87874ee5b8f1514c38032
Author: Evgeny Grin (Karlson2k) <address@hidden>
Date:   Wed Nov 9 23:14:01 2016 +0300

    Use non-blocking sockets for fast responses

commit e05239e5c7c6d073fcc2500c59d3b1c39e44169d
Author: Evgeny Grin (Karlson2k) <address@hidden>
Date:   Wed Nov 9 16:25:02 2016 +0300

    Mark connection as blocking or non-blocking

commit be045a04763cabf3c3416427499060a3bf68fd1e
Author: Evgeny Grin (Karlson2k) <address@hidden>
Date:   Thu Nov 10 15:59:36 2016 +0300

    Prevent accidental double-cleanup

-----------------------------------------------------------------------

Summary of changes:
 src/microhttpd/connection.c |   4 ++
 src/microhttpd/daemon.c     | 122 +++++++++++++++++++++++++-------------------
 src/microhttpd/internal.h   |  11 ++++
 3 files changed, 84 insertions(+), 53 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 3b9b0ce..6483f36 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2663,6 +2663,10 @@ cleanup_connection (struct MHD_Connection *connection)
 {
   struct MHD_Daemon *daemon = connection->daemon;
 
+  if (connection->in_cleanup)
+    return; /* Prevent double cleanup. */
+
+  connection->in_cleanup = !0;
   if (NULL != connection->response)
     {
       MHD_destroy_response (connection->response);
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 206b1a6..fda8283 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -889,8 +889,9 @@ call_handlers (struct MHD_Connection *con,
                int force_close)
 {
   struct MHD_Daemon *daemon = con->daemon;
-  int had_response_before_idle;
   int ret;
+  /* Initial state of connection. */
+  bool was_initing = (con->state == MHD_CONNECTION_INIT);
 
 #ifdef HTTPS_SUPPORT
   if (MHD_YES == con->tls_read_ready)
@@ -900,25 +901,37 @@ call_handlers (struct MHD_Connection *con,
     con->read_handler (con);
   if (write_ready)
     con->write_handler (con);
-  had_response_before_idle = (NULL != con->response);
   if (force_close)
     MHD_connection_close_ (con,
                            MHD_REQUEST_TERMINATED_WITH_ERROR);
   ret = con->idle_handler (con);
-  /* If we're in TURBO mode, and got a response object,
-     try opportunistically to just call write immediately.  */
-  if ( (! force_close) &&
-       (MHD_YES == ret) &&
-       (0 != (daemon->options & MHD_USE_EPOLL_TURBO)) &&
-       (NULL != con->response) &&
-       (MHD_NO == had_response_before_idle) )
-    {
-      /* first 'write' gets the header, then 'idle'
-         readies the body, then 2nd 'write' may send
-         the body. */
+
+  /* Fast track for fast connections. */
+  /* If full request was read by single read_handler() invocation
+     and headers were completely prepared by single idle_handler()
+     then try not to wait for next sockets polling and send response
+     immediately.
+     As writeability of socket was not checked and it may have
+     some data pending in system buffers, use this optimization
+     only for non-blocking sockets. */
+  if ( (MHD_NO != ret) &&
+       (was_initing) &&
+       (MHD_CONNECTION_HEADERS_SENDING == con->state) &&
+       (con->sk_nonblck) )
+    {
       con->write_handler (con);
-      if (MHD_YES == (ret = con->idle_handler (con)))
-        con->write_handler (con);
+      /* If all headers were sent by single write_handler() - continue. */
+      if (MHD_CONNECTION_HEADERS_SENT == con->state)
+        {
+          ret = con->idle_handler (con);
+          if ( (MHD_NO != ret) &&
+               ( (MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
+                 (MHD_CONNECTION_CHUNKED_BODY_READY == con->state) ) )
+            {
+              con->write_handler (con);
+              ret = con->idle_handler (con);
+          }
+        }
     }
   return ret;
 }
@@ -1940,6 +1953,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon);
  * @param addrlen number of bytes in @a addr
  * @param external_add perform additional operations needed due
  *        to the application calling us directly
+ * @param non_blck indicate that socket in non-blocking mode
  * @return #MHD_YES on success, #MHD_NO if this daemon could
  *        not handle the connection (i.e. malloc failed, etc).
  *        The socket will be closed in any case; 'errno' is
@@ -1950,7 +1964,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
                         MHD_socket client_socket,
                         const struct sockaddr *addr,
                         socklen_t addrlen,
-                        int external_add)
+                        int external_add,
+                        bool non_blck)
 {
   struct MHD_Connection *connection;
   unsigned int i;
@@ -1970,7 +1985,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
                                             client_socket,
                                             addr,
                                             addrlen,
-                                            external_add);
+                                            external_add,
+                                            non_blck);
         }
       /* all pools are at their connection limit, must refuse */
       MHD_socket_close_chk_ (client_socket);
@@ -2119,31 +2135,20 @@ internal_add_connection (struct MHD_Daemon *daemon,
           addrlen);
   connection->addr_len = addrlen;
   connection->socket_fd = client_socket;
+  connection->sk_nonblck = non_blck;
   connection->daemon = daemon;
   connection->last_activity = MHD_monotonic_sec_counter();
 
-  /* set default connection handlers  */
-  MHD_set_http_callbacks_ (connection);
-  connection->recv_cls = &recv_param_adapter;
-  connection->send_cls = &send_param_adapter;
-
-  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
+  if (0 == (daemon->options & MHD_USE_TLS))
     {
-      /* in turbo mode, we assume that non-blocking was already set
-        by 'accept4' or whoever calls 'MHD_add_connection' */
-      if (! MHD_socket_nonblocking_ (connection->socket_fd))
-        {
-#ifdef HAVE_MESSAGES
-          MHD_DLOG (connection->daemon,
-                    _("Failed to set nonblocking mode on connection socket: 
%s\n"),
-                    MHD_socket_last_strerr_());
-#endif
-        }
+      /* set default connection handlers  */
+      MHD_set_http_callbacks_ (connection);
+      connection->recv_cls = &recv_param_adapter;
+      connection->send_cls = &send_param_adapter;
     }
-
-#ifdef HTTPS_SUPPORT
-  if (0 != (daemon->options & MHD_USE_TLS))
+  else
     {
+#ifdef HTTPS_SUPPORT
       connection->recv_cls = &recv_tls_adapter;
       connection->send_cls = &send_tls_adapter;
       connection->state = MHD_TLS_CONNECTION_INIT;
@@ -2188,8 +2193,11 @@ internal_add_connection (struct MHD_Daemon *daemon,
       if (daemon->https_mem_trust)
          gnutls_certificate_server_set_request (connection->tls_session,
                                                 GNUTLS_CERT_REQUEST);
+#else  /* ! HTTPS_SUPPORT */
+      goto cleanup;
+#endif /* ! HTTPS_SUPPORT */
     }
-#endif /* HTTPS_SUPPORT */
+
 
   if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
   {
@@ -2581,31 +2589,33 @@ MHD_add_connection (struct MHD_Daemon *daemon,
                    const struct sockaddr *addr,
                    socklen_t addrlen)
 {
-  /* internal_add_connection() assume that non-blocking is
-     already set in MHD_USE_EPOLL_TURBO mode */
-  if (0 != (daemon->options & MHD_USE_EPOLL_TURBO))
+  bool sk_nonbl;
+  if (! MHD_socket_nonblocking_ (client_socket))
     {
-      if (! MHD_socket_nonblocking_ (client_socket))
-        {
 #ifdef HAVE_MESSAGES
-          MHD_DLOG (daemon,
-                    _("Failed to set nonblocking mode on new client socket: 
%s\n"),
-                    MHD_socket_last_strerr_());
+      MHD_DLOG (daemon,
+                _("Failed to set nonblocking mode on new client socket: %s\n"),
+                MHD_socket_last_strerr_());
 #endif
-        }
-      if (! MHD_socket_noninheritable_ (client_socket))
-        {
+      sk_nonbl = 0;
+    }
+  else
+    sk_nonbl = !0;
+
+  if ( (0 != (daemon->options & MHD_USE_EPOLL_TURBO)) &&
+       (! MHD_socket_noninheritable_ (client_socket)) )
+    {
 #ifdef HAVE_MESSAGES
-          MHD_DLOG (daemon,
-                    _("Failed to set noninheritable mode on new client 
socket.\n"));
+      MHD_DLOG (daemon,
+                _("Failed to set noninheritable mode on new client 
socket.\n"));
 #endif
-        }
     }
   return internal_add_connection (daemon,
                                  client_socket,
                                  addr,
                                   addrlen,
-                                 MHD_YES);
+                                 MHD_YES,
+                                 sk_nonbl);
 }
 
 
@@ -2635,6 +2645,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
   socklen_t addrlen;
   MHD_socket s;
   MHD_socket fd;
+  bool sk_nonbl;
 
   addrlen = sizeof (addrstorage);
   memset (addr,
@@ -2647,10 +2658,12 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
                addr,
                &addrlen,
                MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK);
+  sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
 #else  /* ! USE_ACCEPT4 */
   s = accept (fd,
               addr,
               &addrlen);
+  sk_nonbl = 0;
 #endif /* ! USE_ACCEPT4 */
   if ( (MHD_INVALID_SOCKET == s) ||
        (addrlen <= 0) )
@@ -2708,6 +2721,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
                 MHD_socket_last_strerr_());
 #endif
     }
+  else
+    sk_nonbl = !0;
 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
   if (! MHD_socket_noninheritable_ (s))
@@ -2729,7 +2744,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
                                   s,
                                  addr,
                                   addrlen,
-                                 MHD_NO);
+                                 MHD_NO,
+                                  sk_nonbl);
   return MHD_YES;
 }
 
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 77679aa..b6426df 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -790,6 +790,11 @@ struct MHD_Connection
   MHD_socket socket_fd;
 
   /**
+   * Non-zero if #socket_fd is non-blocking, zero otherwise.
+   */
+  bool sk_nonblck;
+
+  /**
    * Has this socket been closed for reading (i.e.  other side closed
    * the connection)?  If so, we must completely close the connection
    * once we are done sending our response (and stop trying to read
@@ -808,6 +813,12 @@ struct MHD_Connection
    */
   int in_idle;
 
+  /**
+   * Are we currently inside the "idle" handler (to avoid recursively
+   * invoking it).
+   */
+  bool in_cleanup;
+
 #ifdef EPOLL_SUPPORT
   /**
    * What is the state of this socket in relation to epoll?


hooks/post-receive
-- 
GNU libmicrohttpd



reply via email to

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