libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

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:
Msrc/mhd2/daemon_start.c | 123+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
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)