gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 05/13: thread-per-connection: improved timeout handling


From: gnunet
Subject: [libmicrohttpd] 05/13: thread-per-connection: improved timeout handling for 'poll()' mode, fixed short busy-waiting
Date: Wed, 27 Apr 2022 21:25:13 +0200

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 4ebe2aa5f995d4cbf45c63d277ad1653ffca7725
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Wed Apr 27 14:56:18 2022 +0300

    thread-per-connection: improved timeout handling for 'poll()' mode, fixed 
short busy-waiting
    
    * Avoid unneeded wake-ups
    * More precise timeout with milliseconds accuracy
    * Fixed potential short (less than one second) busy waiting when
      connection is about to expire.
---
 configure.ac                |  3 +-
 src/microhttpd/daemon.c     | 90 ++++++++++++++++++++++++++-------------------
 src/microhttpd/mhd_limits.h |  8 ++++
 3 files changed, 62 insertions(+), 39 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8d5d9e1f..a6af4004 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1438,7 +1438,9 @@ struct timeval test_var;
 AC_DEFINE_UNQUOTED([SIZEOF_STRUCT_TIMEVAL_TV_SEC], 
[$mhd_cv_size_timeval_tv_sec],
   [The size of `tv_sec' member of `struct timeval', as computed by sizeof])
 AC_CHECK_SIZEOF([uint64_t], [], [[#include <stdint.h>]])
+AC_CHECK_SIZEOF([int], [], [[#include <stdint.h>]])
 AC_CHECK_SIZEOF([unsigned int], [], [[#include <stdint.h>]])
+AC_CHECK_SIZEOF([unsigned long long], [], [[#include <stdint.h>]])
 AC_CHECK_SIZEOF([size_t], [],
   [[
 #ifdef HAVE_STDLIB_H
@@ -1450,7 +1452,6 @@ AC_CHECK_SIZEOF([size_t], [],
 #include <stdio.h>
   ]]
 )
-AC_CHECK_SIZEOF([unsigned long long], [], [[#include <stdint.h>]])
 
 AC_CHECK_HEADERS([dlfcn.h],[have_tlsplugin=yes],[have_tlsplugin=no], 
[AC_INCLUDES_DEFAULT])
 AM_CONDITIONAL([MHD_HAVE_TLS_PLUGIN], [[test "x$have_tlsplugin" = xyes]])
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index e9207490..1ec58e06 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1836,8 +1836,8 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
  * Get maximum wait period for the connection (the amount of time left before
  * connection time out)
  * @param c the connection to check
- * @return the maximum wait period before the connection must be processed
- *         again.
+ * @return the maximum number of millisecond before the connection must be
+ *         processed again.
  */
 static uint64_t
 connection_get_wait (struct MHD_Connection *c)
@@ -1897,8 +1897,6 @@ thread_main_handle_connection (void *data)
   fd_set ws;
   fd_set es;
   MHD_socket maxsock;
-  struct timeval tv;
-  struct timeval *tvp;
 #if WINDOWS
 #ifdef HAVE_POLL
   int extra_slot;
@@ -1922,6 +1920,7 @@ thread_main_handle_connection (void *data)
   while ( (! daemon->shutdown) &&
           (MHD_CONNECTION_CLOSED != con->state) )
   {
+    bool use_zero_timeout;
 #ifdef UPGRADE_SUPPORT
     struct MHD_UpgradeResponseHandle *const urh = con->urh;
 #else  /* ! UPGRADE_SUPPORT */
@@ -1999,40 +1998,40 @@ thread_main_handle_connection (void *data)
       was_suspended = false;
     }
 
-    tvp = NULL;
-
-    if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
+    use_zero_timeout = ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
 #ifdef HTTPS_SUPPORT
-         || ( (con->tls_read_ready) &&
-              (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
+                         || ( (con->tls_read_ready) && \
+                              (MHD_EVENT_LOOP_INFO_READ ==
+                               con->event_loop_info) )
 #endif /* HTTPS_SUPPORT */
-         )
-    {
-      /* do not block: more data may be inside of TLS buffers waiting or
-       * application must provide response data */
-      tv.tv_sec = 0;
-      tv.tv_usec = 0;
-      tvp = &tv;
-    }
-    if ( (NULL == tvp) &&
-         (con->connection_timeout_ms > 0) )
-    {
-      const uint64_t mseconds_left = connection_get_wait (con);
-#if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
-      if (mseconds_left / 1000 > TIMEVAL_TV_SEC_MAX)
-        tv.tv_sec = TIMEVAL_TV_SEC_MAX;
-      else
-#endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */
-      tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) mseconds_left / 1000;
-
-      tv.tv_usec = (mseconds_left % 1000) * 1000;
-
-      tvp = &tv;
-    }
+                         );
     if (! use_poll)
     {
       /* use select */
       bool err_state = false;
+      struct timeval tv;
+      struct timeval *tvp;
+      if (use_zero_timeout)
+      {
+        tv.tv_sec = 0;
+        tv.tv_usec = 0;
+        tvp = &tv;
+      }
+      else if (con->connection_timeout_ms > 0)
+      {
+        const uint64_t mseconds_left = connection_get_wait (con);
+#if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
+        if (mseconds_left / 1000 > TIMEVAL_TV_SEC_MAX)
+          tv.tv_sec = TIMEVAL_TV_SEC_MAX;
+        else
+#endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */
+        tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) mseconds_left / 1000;
+
+        tv.tv_usec = ((uint16_t) (mseconds_left % 1000)) * 1000;
+        tvp = &tv;
+      }
+      else
+        tvp = NULL;
 
       FD_ZERO (&rs);
       FD_ZERO (&ws);
@@ -2124,7 +2123,22 @@ thread_main_handle_connection (void *data)
 #ifdef HAVE_POLL
     else
     {
+      int timeout_val;
       /* use poll */
+      if (use_zero_timeout)
+        timeout_val = 0;
+      else if (con->connection_timeout_ms > 0)
+      {
+        const uint64_t mseconds_left = connection_get_wait (con);
+#if SIZEOF_UINT64_T >= SIZEOF_INT
+        if (mseconds_left >= INT_MAX)
+          timeout_val = INT_MAX;
+        else
+#endif /* SIZEOF_UINT64_T >= SIZEOF_INT */
+        timeout_val = (int) mseconds_left;
+      }
+      else
+        timeout_val = -1;
       memset (&p,
               0,
               sizeof (p));
@@ -2160,7 +2174,7 @@ thread_main_handle_connection (void *data)
 #else
                          1,
 #endif
-                         (NULL == tvp) ? -1 : (tv.tv_sec * 1000)) < 0)
+                         timeout_val) < 0)
       {
         if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
           continue;
@@ -4617,7 +4631,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
     p[poll_count].fd = ls;
     p[poll_count].events = POLLIN;
     p[poll_count].revents = 0;
-    poll_listen = poll_count;
+    poll_listen = (int) poll_count;
     poll_count++;
   }
   if (MHD_ITC_IS_VALID_ (daemon->itc))
@@ -4625,7 +4639,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
     p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
     p[poll_count].events = POLLIN;
     p[poll_count].revents = 0;
-    poll_itc_idx = poll_count;
+    poll_itc_idx = (int) poll_count;
     poll_count++;
   }
 
@@ -4653,7 +4667,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
 #endif
     return MHD_NO;
   }
-  if ( (-1 != poll_itc_idx) &&
+  if ( (0 <= poll_itc_idx) &&
        (0 != (p[poll_itc_idx].revents & POLLIN)) )
     MHD_itc_clear_ (daemon->itc);
 
@@ -4665,7 +4679,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
   if (daemon->have_new)
     new_connections_list_process_ (daemon);
 
-  if ( (-1 != poll_listen) &&
+  if ( (0 <= poll_listen) &&
        (0 != (p[poll_listen].revents & POLLIN)) )
     (void) MHD_accept_connection (daemon);
   return MHD_YES;
@@ -6932,7 +6946,7 @@ MHD_start_daemon_va (unsigned int flags,
     }
 #endif
     if (listen (listen_fd,
-                daemon->listen_backlog_size) < 0)
+                (int) daemon->listen_backlog_size) < 0)
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
diff --git a/src/microhttpd/mhd_limits.h b/src/microhttpd/mhd_limits.h
index a4e15423..b61da5f4 100644
--- a/src/microhttpd/mhd_limits.h
+++ b/src/microhttpd/mhd_limits.h
@@ -38,6 +38,14 @@
   ( (type) ((( ((type) 1) << (sizeof(type) * 8 - 2)) - 1) * 2 + 1) )
 #define MHD_TYPE_IS_SIGNED_(type) (((type) 0)>((type) - 1))
 
+#ifndef INT_MAX
+#ifdef __INT_MAX__
+#define INT_MAX __INT_MAX__
+#else  /* ! __UINT_MAX__ */
+#define INT_MAX MHD_SIGNED_TYPE_MAX_ (int)
+#endif /* ! __UINT_MAX__ */
+#endif /* !UINT_MAX */
+
 #ifndef UINT_MAX
 #ifdef __UINT_MAX__
 #define UINT_MAX __UINT_MAX__

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