commit 49b44ba5d3fdfee19d8b9504a8eaa0cbadf65b35
parent 938533d819605c74d3e11e677f591f643cb2c419
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Sat, 2 Aug 2025 23:46:11 +0200
daemon_start: streamlined events selection and pre-init
Diffstat:
1 file changed, 70 insertions(+), 53 deletions(-)
diff --git a/src/mhd2/daemon_start.c b/src/mhd2/daemon_start.c
@@ -156,7 +156,10 @@ daemon_set_basic_settings (struct MHD_Daemon *restrict d,
/**
- * Set the daemon work mode and perform some related checks.
+ * Set the daemon work mode.
+ * This function also checks whether requested work mode is supported by
+ * current build and whether work mode is compatible with requested events
+ * polling technique.
* @param d the daemon object
* @param s the user settings
* @return MHD_SC_OK on success,
@@ -1213,7 +1216,8 @@ detect_listen_type_and_port (struct MHD_Daemon *restrict d)
* Initialise daemon's epoll FD
*/
static MHD_FN_PAR_NONNULL_ (1) enum MHD_StatusCode
-init_epoll (struct MHD_Daemon *restrict d)
+init_epoll (struct MHD_Daemon *restrict d,
+ bool log_failures)
{
int e_fd;
mhd_assert (! mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int));
@@ -1239,15 +1243,17 @@ init_epoll (struct MHD_Daemon *restrict d)
#endif /* ! HAVE_EPOLL_CREATE1 */
if (0 > e_fd)
{
- mhd_LOG_MSG (d, MHD_SC_EPOLL_CTL_CREATE_FAILED, \
- "Failed to create epoll control FD");
+ if (log_failures)
+ mhd_LOG_MSG (d, MHD_SC_EPOLL_CTL_CREATE_FAILED, \
+ "Failed to create epoll control FD");
return MHD_SC_EPOLL_CTL_CREATE_FAILED; /* Failure exit point */
}
if (! mhd_FD_FITS_DAEMON (d, e_fd))
{
- mhd_LOG_MSG (d, MHD_SC_EPOLL_CTL_OUTSIDE_OF_SET_RANGE, \
- "The epoll control FD value is higher than allowed");
+ if (log_failures)
+ mhd_LOG_MSG (d, MHD_SC_EPOLL_CTL_OUTSIDE_OF_SET_RANGE, \
+ "The epoll control FD value is higher than allowed");
(void) close (e_fd);
return MHD_SC_EPOLL_CTL_OUTSIDE_OF_SET_RANGE; /* Failure exit point */
}
@@ -1293,7 +1299,12 @@ daemon_choose_and_preinit_events (struct MHD_Daemon *restrict d,
struct DaemonOptions *restrict s)
{
enum mhd_IntPollType chosen_type;
- bool fallback_syscall_allowed;
+
+ mhd_assert (mhd_POLL_TYPE_NOT_SET_YET == d->events.poll_type);
+
+ mhd_assert ((mhd_WM_INT_EXTERNAL_EVENTS_EDGE != d->wmode_int) || \
+ (mhd_WM_INT_EXTERNAL_EVENTS_LEVEL != d->wmode_int) || \
+ (MHD_SPS_AUTO == s->poll_syscall));
mhd_assert ((mhd_POLL_TYPE_NOT_SET_YET == d->events.poll_type) || \
(mhd_WM_INT_EXTERNAL_EVENTS_EDGE == d->wmode_int) || \
@@ -1306,12 +1317,11 @@ daemon_choose_and_preinit_events (struct MHD_Daemon *restrict d,
mhd_POLL_TYPE_INT_IS_EPOLL (d->events.poll_type))));
/* Check whether the provided parameter is in the range of expected values.
- Only block unsupported values. */
+ Reject unsupported or disabled values. */
switch (s->poll_syscall)
{
case MHD_SPS_AUTO:
chosen_type = mhd_POLL_TYPE_NOT_SET_YET;
- /* The used value is chosen below */
break;
case MHD_SPS_SELECT:
mhd_assert (! mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int));
@@ -1356,65 +1366,71 @@ daemon_choose_and_preinit_events (struct MHD_Daemon *restrict d,
if (mhd_POLL_TYPE_NOT_SET_YET == chosen_type)
{
+ if (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int))
+ chosen_type = mhd_POLL_TYPE_EXT;
+ }
+
#ifdef MHD_SUPPORT_EPOLL
- bool edge_trig_allowed;
- edge_trig_allowed = true;
-# ifdef MHD_SUPPORT_HTTPS
- if ((edge_trig_allowed) &&
- (MHD_TLS_BACKEND_NONE != s->tls))
- edge_trig_allowed = mhd_tls_is_edge_trigg_supported (s);
-# endif /* MHD_SUPPORT_HTTPS */
-#endif /* MHD_SUPPORT_EPOLL */
- fallback_syscall_allowed = true;
+ /* Try 'epoll' if needed or possible */
+ if ((mhd_POLL_TYPE_NOT_SET_YET == chosen_type)
+ || (mhd_POLL_TYPE_EPOLL == chosen_type))
+ {
+ bool epoll_required;
+ bool epoll_allowed;
- if (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int))
+ epoll_required = false;
+ if (mhd_POLL_TYPE_EPOLL == chosen_type)
{
- chosen_type = mhd_POLL_TYPE_EXT;
+ mhd_assert (! mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int));
+ epoll_required = true;
}
-#ifdef MHD_SUPPORT_EPOLL
else if (MHD_WM_EXTERNAL_SINGLE_FD_WATCH == s->work_mode.mode)
{
- fallback_syscall_allowed = false;
- chosen_type = mhd_POLL_TYPE_EPOLL; /* without fallback */
+ mhd_assert (! mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int));
+ epoll_required = true;
}
- else if ((! mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int)) &&
- (edge_trig_allowed))
- chosen_type = mhd_POLL_TYPE_EPOLL; /* with possible fallback */
-#endif
- else
+
+ epoll_allowed = true;
+ if (mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int))
{
-#if defined(MHD_SUPPORT_POLL)
- chosen_type = mhd_POLL_TYPE_POLL;
-#elif defined(MHD_SUPPORT_SELECT)
- chosen_type = mhd_POLL_TYPE_SELECT;
-#else
- (void) 0; /* Do nothing. Mute compiler warning */
-#endif
+ mhd_assert (! epoll_required);
+ epoll_allowed = false;
}
- }
- else
- fallback_syscall_allowed = false;
-
- /* Try 'epoll' if possible */
-#ifdef MHD_SUPPORT_EPOLL
- if (mhd_POLL_TYPE_EPOLL == chosen_type)
- {
- enum MHD_StatusCode epoll_res;
+# ifdef MHD_SUPPORT_HTTPS
+ else if (MHD_TLS_BACKEND_NONE != s->tls)
+ {
+ if (! epoll_required)
+ epoll_allowed = mhd_tls_is_edge_trigg_supported (s);
+ /* If 'epoll' is required, but TLS backend does not support it,
+ then continue with 'epoll' here and fail at TLS initialisation. */
+ /* TODO: fail here */
+ }
+# endif /* MHD_SUPPORT_HTTPS */
- mhd_assert (! mhd_WM_INT_IS_THREAD_PER_CONN (d->wmode_int));
- epoll_res = init_epoll (d);
+ mhd_assert (epoll_allowed || ! epoll_required);
- if (MHD_SC_OK != epoll_res)
+ if (epoll_allowed)
{
- if (! fallback_syscall_allowed)
- return epoll_res; /* Cannot init epoll, but epoll is required */
- chosen_type = mhd_POLL_TYPE_NOT_SET_YET; /* Choose again */
+ enum MHD_StatusCode epoll_res;
+
+ epoll_res = init_epoll (d,
+ epoll_required);
+ if (MHD_SC_OK == epoll_res)
+ chosen_type = mhd_POLL_TYPE_EPOLL;
+ else
+ {
+ if (epoll_required)
+ return epoll_res;
+ mhd_assert (mhd_POLL_TYPE_NOT_SET_YET == chosen_type);
+ }
}
+ else
+ mhd_assert (mhd_POLL_TYPE_EPOLL != chosen_type);
}
mhd_assert ((mhd_POLL_TYPE_EPOLL != d->events.poll_type) || \
(0 < d->events.data.epoll.e_fd));
-#else /* ! MHD_SUPPORT_EPOLL */
- (void) fallback_syscall_allowed; /* Mute compiler warning */
+ mhd_assert ((mhd_POLL_TYPE_EPOLL == d->events.poll_type) == \
+ (mhd_POLL_TYPE_EPOLL == chosen_type));
#endif /* ! MHD_SUPPORT_EPOLL */
if (mhd_POLL_TYPE_NOT_SET_YET == chosen_type)
@@ -2925,7 +2941,8 @@ init_workers_pool (struct MHD_Daemon *restrict d,
d->events.data.epoll.e_fd = MHD_INVALID_SOCKET;
}
else
- res = init_epoll (worker);
+ res = init_epoll (worker,
+ true);
}
#endif /* MHD_SUPPORT_EPOLL */
if (MHD_SC_OK == res)