[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.
- [libmicrohttpd] branch master updated (54e12358 -> d14fc3b3), gnunet, 2022/04/27
- [libmicrohttpd] 04/13: thread-per-connection: do not cache connection timeout, gnunet, 2022/04/27
- [libmicrohttpd] 03/13: Response from callback: do allow negative return amounts, except predefined values, gnunet, 2022/04/27
- [libmicrohttpd] 01/13: MHD_itc_clear_(): simplified eventfd version, gnunet, 2022/04/27
- [libmicrohttpd] 08/13: Added new function MHD_get_timeout64s(), gnunet, 2022/04/27
- [libmicrohttpd] 02/13: Fixed compiler warnings of implicit casting, which could change the value, gnunet, 2022/04/27
- [libmicrohttpd] 06/13: Added new function MHD_get_timeout64(), gnunet, 2022/04/27
- [libmicrohttpd] 09/13: daemon: added workaround for 'uncrustify' broken formatting, gnunet, 2022/04/27
- [libmicrohttpd] 07/13: get_timeout_millisec_(): refactoring for readability, gnunet, 2022/04/27
- [libmicrohttpd] 05/13: thread-per-connection: improved timeout handling for 'poll()' mode, fixed short busy-waiting,
gnunet <=
- [libmicrohttpd] 10/13: Use new function MHD_get_timeout64() in MHD code, gnunet, 2022/04/27
- [libmicrohttpd] 11/13: mhd_send: added safe default value if sysconf() is broken, gnunet, 2022/04/27
- [libmicrohttpd] 12/13: Fixes related to implicit cast warnings, gnunet, 2022/04/27
- [libmicrohttpd] 13/13: MHD_get_timeout*(): improved doxy, gnunet, 2022/04/27