commit d5702562a9a9383960af7fea19984b826bc41079
parent a56fe4fa5782cc7c3994fdbb9c497d30fa36d945
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Sat, 27 Dec 2025 14:31:13 +0100
Corrected max wait time used for sockets polling
Diffstat:
2 files changed, 102 insertions(+), 31 deletions(-)
diff --git a/src/mhd2/events_process.c b/src/mhd2/events_process.c
@@ -48,6 +48,8 @@
#include "mhd_assert.h"
#include "mhd_unreachable.h"
+#include "mhd_predict.h"
+
#if defined(mhd_DEBUG_SUSPEND_RESUME) || defined(mhd_DEBUG_POLLING_FDS)
# include <stdio.h>
#endif /* mhd_DEBUG_SUSPEND_RESUME */
@@ -321,16 +323,21 @@ daemon_resume_conns_if_needed (struct MHD_Daemon *restrict d)
}
+#if defined (MHD_SUPPORT_POLL) || defined(MHD_SUPPORT_EPOLL)
+
mhd_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE
static MHD_FN_PAR_NONNULL_ALL_ int
-get_max_wait (struct MHD_Daemon *restrict d)
+get_max_wait (const struct MHD_Daemon *restrict d)
{
- uint_fast64_t ui64_wait = mhd_daemon_get_wait_max (d);
+ const uint_fast64_t ui64_wait = mhd_daemon_get_wait_max (d);
int i_wait = (int) ui64_wait;
- if ((0 > i_wait) ||
- (ui64_wait != (uint_fast64_t) i_wait))
+ if (MHD_WAIT_INDEFINITELY <= ui64_wait)
+ return -1;
+
+ if (mhd_COND_ALMOST_NEVER ((0 > i_wait) ||
+ (ui64_wait != (uint_fast64_t) i_wait)))
return INT_MAX;
return i_wait;
@@ -340,6 +347,9 @@ get_max_wait (struct MHD_Daemon *restrict d)
mhd_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE
/* End of warning-less data truncation */
+#endif
+/* MHD_SUPPORT_POLL || MHD_SUPPORT_EPOLL */
+
MHD_FN_PAR_NONNULL_ (1) static void
update_conn_net_status (struct MHD_Daemon *restrict d,
@@ -1130,6 +1140,61 @@ select_update_statuses_from_fdsets_and_resume_conn (struct MHD_Daemon *d,
/**
+ * Get pointer to struct timeval for select() for polling daemon's sockets
+ * @param d the daemon to use
+ * @param[out] tmvl to pointer to the allocated struct timeval
+ * @return the @a tmvl pointer (with maximum wait value set)
+ * or NULL if select may wait indefinitely
+ */
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_ (2) struct timeval *
+get_timeval_for_select (const struct MHD_Daemon *restrict d,
+ struct timeval *tmvl)
+{
+ const uint_fast64_t max_wait = mhd_daemon_get_wait_max (d);
+#ifdef HAVE_TIME_T
+ time_t max_wait_secs = (time_t) (max_wait / 1000u);
+#else /* ! HAVE_TIME_T */
+ long max_wait_secs = (long) (max_wait / 1000u);
+#endif /* ! HAVE_TIME_T */
+#ifdef HAVE_SUSECONDS_T
+ suseconds_t max_wait_usecs = (suseconds_t) ((max_wait % 1000u) * 1000u);
+#else /* ! HAVE_SUSECONDS_T */
+ long max_wait_usecs = (long) ((max_wait % 1000u) * 1000u);
+#endif /* ! HAVE_SUSECONDS_T */
+
+ if (MHD_WAIT_INDEFINITELY <= max_wait)
+ return NULL;
+
+ if (0u == max_wait)
+ {
+ tmvl->tv_sec = 0;
+ tmvl->tv_usec = 0;
+
+ return tmvl;
+ }
+
+ if (mhd_COND_ALMOST_NEVER ((max_wait / 1000u !=
+ (uint_fast64_t) max_wait_secs) ||
+ (max_wait_secs <= 0)))
+ {
+ /* Do not bother figuring out the real maximum 'time_t' value.
+ '0x7FFFFFFF' is large enough to be already unrealistic and should
+ fit most of signed or unsigned time_t types. */
+ tmvl->tv_sec = 0x7FFFFFFF;
+ tmvl->tv_usec = 0;
+
+ return tmvl;
+ }
+
+ tmvl->tv_sec = max_wait_secs;
+ tmvl->tv_usec = max_wait_usecs;
+
+ return tmvl;
+}
+
+
+/**
* Update states of all connections, check for connection pending
* to be accept()'ed, check for the events on ITC; resume connections
* @param listen_only set to 'true' if connections's sockets should NOT
@@ -1143,51 +1208,57 @@ get_all_net_updates_by_select_and_resume_conn (struct MHD_Daemon *restrict d,
bool listen_only)
{
int max_socket;
- int max_wait;
- struct timeval tmvl;
+ struct timeval tmvl_value;
+ struct timeval *tmvl_ptr;
int num_events;
mhd_assert (mhd_POLL_TYPE_SELECT == d->events.poll_type);
max_socket = select_update_fdsets (d,
listen_only);
- max_wait = get_max_wait (d); // TODO: use correct timeout value
+ tmvl_ptr = get_timeval_for_select (d,
+ &tmvl_value);
#ifdef MHD_SOCKETS_KIND_WINSOCK
if (0 == max_socket)
{
- Sleep ((unsigned int) max_wait);
+ Sleep (tmvl_ptr ? tmvl_ptr->tv_sec : 600);
return true;
}
#endif /* MHD_SOCKETS_KIND_WINSOCK */
- tmvl.tv_sec = max_wait / 1000;
-#ifndef MHD_SOCKETS_KIND_WINSOCK
- tmvl.tv_usec = (uint_least16_t) ((max_wait % 1000) * 1000);
-#else
- tmvl.tv_usec = (int) ((max_wait % 1000) * 1000);
-#endif
-
#ifdef mhd_DEBUG_POLLING_FDS
- fprintf (stderr,
- "### (Starting) select(%d, rfds, wfds, efds, [%llu, %llu])...\n",
- max_socket + 1,
- (unsigned long long) tmvl.tv_sec,
- (unsigned long long) tmvl.tv_usec);
+ if (NULL != tmvl_ptr)
+ fprintf (stderr,
+ "### (Starting) select(%d, rfds, wfds, efds, [%llu, %llu])...\n",
+ max_socket + 1,
+ (unsigned long long) tmvl_ptr->tv_sec,
+ (unsigned long long) tmvl_ptr->tv_usec);
+ else
+ fprintf (stderr,
+ "### (Starting) select(%d, rfds, wfds, efds, [NULL])...\n",
+ max_socket + 1);
#endif /* mhd_DEBUG_POLLING_FDS */
num_events = select (max_socket + 1,
d->events.data.select.rfds,
d->events.data.select.wfds,
d->events.data.select.efds,
- &tmvl);
+ tmvl_ptr);
#ifdef mhd_DEBUG_POLLING_FDS
- fprintf (stderr,
- "### (Finished) select(%d, rfds, wfds, efds, ->[%llu, %llu]) -> "
- "%d\n",
- max_socket + 1,
- (unsigned long long) tmvl.tv_sec,
- (unsigned long long) tmvl.tv_usec,
- num_events);
+ if (NULL != tmvl_ptr)
+ fprintf (stderr,
+ "### (Finished) select(%d, rfds, wfds, efds, ->[%llu, %llu]) -> "
+ "%d\n",
+ max_socket + 1,
+ (unsigned long long) tmvl_ptr->tv_sec,
+ (unsigned long long) tmvl_ptr->tv_usec,
+ num_events);
+ else
+ fprintf (stderr,
+ "### (Finished) select(%d, rfds, wfds, efds, [NULL]) -> "
+ "%d\n",
+ max_socket + 1,
+ num_events);
#endif /* mhd_DEBUG_POLLING_FDS */
if (0 > num_events)
@@ -1504,7 +1575,7 @@ get_all_net_updates_by_poll (struct MHD_Daemon *restrict d,
num_fds = poll_update_fds (d, listen_only);
// TODO: handle empty list situation
- max_wait = get_max_wait (d); // TODO: use correct timeout value
+ max_wait = get_max_wait (d);
#ifdef mhd_DEBUG_POLLING_FDS
fprintf (stderr,
@@ -1697,7 +1768,7 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
max_events = (int) d->events.data.epoll.num_elements;
events_processed = 0;
- max_wait = get_max_wait (d); // TODO: use correct timeout value
+ max_wait = get_max_wait (d);
do
{
#ifdef mhd_DEBUG_POLLING_FDS
diff --git a/src/mhd2/events_process.h b/src/mhd2/events_process.h
@@ -87,7 +87,7 @@ mhd_worker_connection (void *cls);
* #MHD_WAIT_INDEFINITELY if wait time is not limited
*/
MHD_INTERNAL uint_fast64_t
-mhd_daemon_get_wait_max (struct MHD_Daemon *restrict d)
+mhd_daemon_get_wait_max (const struct MHD_Daemon *restrict d)
MHD_FN_PAR_NONNULL_ALL_;
/**