Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Yegor Yefremov via buildroot <buildroot@buildroot.org>
To: buildroot@buildroot.org
Cc: Bernd Kuhls <bernd@kuhls.net>,
	Will Newton <will.newton@gmail.com>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: [Buildroot] [PATCH v2] package/libmicrohttpd: fix build without thread support
Date: Wed, 21 Oct 2026 14:52:14 +0200	[thread overview]
Message-ID: <20261021125214.141014-1-yegorslists@googlemail.com> (raw)
In-Reply-To: <20260926133654.2836794-1-yegorslists@googlemail.com>

When the toolchain has no thread support, libmicrohttpd is configured
with --with-threads=none. In that case connection_get_wait() is not
compiled, because it is defined inside the
"#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)"
region, but MHD_get_timeout64(), which is built unconditionally, calls
it:

daemon.c: In function 'MHD_get_timeout64':
daemon.c:4524:18: error: implicit declaration of function 'connection_get_wait' [-Wimplicit-function-declaration]

Add a patch, submitted upstream, that moves connection_get_wait() out
of the threads-only region.

The faulty code was introduced upstream by commit 73c43a7ef7bd ("Added
workaround for system clock jumps back"), first released in v0.9.75,
which added connection_get_wait() inside the threads-only region and
at the same time called it from MHD_get_timeout().

This issue has been present since commit 8ec001b467e2
("package/libmicrohttpd: bump version to 0.9.75"), which pulled in
that upstream code. It therefore affects 2022.02 and later, and all
maintained branches (2025.02.x, 2025.11.x, 2026.02.x, 2026.05.x and
2026.08.x). However, it only turns into a build failure with GCC >= 14,
as implicit function declarations are errors by default since GCC 14
[1]; with older GCC versions only a warning is emitted.

[1] https://gcc.gnu.org/gcc-14/porting_to.html#implicit-function-declaration

Fixes:
https://autobuild.buildroot.org/results/10f33829552059264104623353a9ec1584b08e4f

Fixes: 8ec001b467e22904c0a7ec5780d83afd44ad78f3 ("package/libmicrohttpd: bump version to 0.9.75")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
Changes v1 -> v2:
  - identify the commit that introduced the issue, add a Fixes: tag
    and explain that the failure only shows up with GCC >= 14
    (suggested by Thomas Petazzoni)

 ...t-thread-support-connection_get_wait.patch | 145 ++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 package/libmicrohttpd/0001-fix-build-without-thread-support-connection_get_wait.patch

diff --git a/package/libmicrohttpd/0001-fix-build-without-thread-support-connection_get_wait.patch b/package/libmicrohttpd/0001-fix-build-without-thread-support-connection_get_wait.patch
new file mode 100644
index 0000000000..d7f93f57f3
--- /dev/null
+++ b/package/libmicrohttpd/0001-fix-build-without-thread-support-connection_get_wait.patch
@@ -0,0 +1,145 @@
+From b9da2097d719dbd125849f2e344d0a7d80b56da6 Mon Sep 17 00:00:00 2001
+From: Yegor Yefremov <yegorslists@googlemail.com>
+Date: Sat, 26 Sep 2026 12:08:52 +0200
+Subject: [PATCH] fix build without thread support: connection_get_wait() must
+ be unconditional
+
+connection_get_wait() was defined inside the
+"#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)"
+region, but MHD_get_timeout64(), which is compiled unconditionally,
+calls it.  When MHD is configured with --with-threads=none the
+definition is not compiled and the build fails:
+
+  daemon.c: In function 'MHD_get_timeout64':
+  daemon.c:4524:18: error: implicit declaration of function
+    'connection_get_wait' [-Wimplicit-function-declaration]
+
+Move the function above the threads-only region.  Pure code motion,
+no functional change; the two thread-only call sites in
+thread_main_handle_connection() still follow the definition.
+
+Found while cross-compiling for a Buildroot mips64el/uClibc toolchain
+without thread support (--with-threads=none).
+
+Upstream: https://lists.gnu.org/archive/html/libmicrohttpd/2026-08/msg00002.html
+Assisted-by: Claude:claude-opus-5
+Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
+---
+ src/microhttpd/daemon.c | 97 +++++++++++++++++++++--------------------
+ 1 file changed, 49 insertions(+), 48 deletions(-)
+
+diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
+index b42d4ee..081d9a6 100644
+--- a/src/microhttpd/daemon.c
++++ b/src/microhttpd/daemon.c
+@@ -1847,6 +1847,55 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
+ 
+ #endif /* HTTPS_SUPPORT  && UPGRADE_SUPPORT */
+ 
++
++/**
++ * 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 number of millisecond before the connection must be
++ *         processed again.
++ */
++static uint64_t
++connection_get_wait (struct MHD_Connection *c)
++{
++  const uint64_t now = MHD_monotonic_msec_counter ();
++  const uint64_t since_actv = now - c->last_activity;
++  const uint64_t timeout = c->connection_timeout_ms;
++  uint64_t mseconds_left;
++
++  mhd_assert (0 != timeout);
++  /* Keep the next lines in sync with #connection_check_timedout() to avoid
++   * undesired side-effects like busy-waiting. */
++  if (timeout < since_actv)
++  {
++    if (UINT64_MAX / 2 < since_actv)
++    {
++      const uint64_t jump_back = c->last_activity - now;
++      /* Very unlikely that it is more than quarter-million years pause.
++       * More likely that system clock jumps back. */
++      if (5000 >= jump_back)
++      { /* Jump back is less than 5 seconds, try to recover. */
++        return 100; /* Set wait time to 0.1 seconds */
++      }
++      /* Too large jump back */
++    }
++    return 0; /* Connection has timed out */
++  }
++  else if (since_actv == timeout)
++  {
++    /* Exact match for timeout and time from last activity.
++     * Maybe this is just a precise match or this happens because the timer
++     * resolution is too low.
++     * Set wait time to 0.1 seconds to avoid busy-waiting with low
++     * timer resolution as connection is not timed-out yet. */
++    return 100;
++  }
++  mseconds_left = timeout - since_actv;
++
++  return mseconds_left;
++}
++
++
+ #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ #ifdef UPGRADE_SUPPORT
+ /**
+@@ -2009,54 +2058,6 @@ thread_main_connection_upgrade (struct MHD_Connection *con)
+ #endif /* UPGRADE_SUPPORT */
+ 
+ 
+-/**
+- * 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 number of millisecond before the connection must be
+- *         processed again.
+- */
+-static uint64_t
+-connection_get_wait (struct MHD_Connection *c)
+-{
+-  const uint64_t now = MHD_monotonic_msec_counter ();
+-  const uint64_t since_actv = now - c->last_activity;
+-  const uint64_t timeout = c->connection_timeout_ms;
+-  uint64_t mseconds_left;
+-
+-  mhd_assert (0 != timeout);
+-  /* Keep the next lines in sync with #connection_check_timedout() to avoid
+-   * undesired side-effects like busy-waiting. */
+-  if (timeout < since_actv)
+-  {
+-    if (UINT64_MAX / 2 < since_actv)
+-    {
+-      const uint64_t jump_back = c->last_activity - now;
+-      /* Very unlikely that it is more than quarter-million years pause.
+-       * More likely that system clock jumps back. */
+-      if (5000 >= jump_back)
+-      { /* Jump back is less than 5 seconds, try to recover. */
+-        return 100; /* Set wait time to 0.1 seconds */
+-      }
+-      /* Too large jump back */
+-    }
+-    return 0; /* Connection has timed out */
+-  }
+-  else if (since_actv == timeout)
+-  {
+-    /* Exact match for timeout and time from last activity.
+-     * Maybe this is just a precise match or this happens because the timer
+-     * resolution is too low.
+-     * Set wait time to 0.1 seconds to avoid busy-waiting with low
+-     * timer resolution as connection is not timed-out yet. */
+-    return 100;
+-  }
+-  mseconds_left = timeout - since_actv;
+-
+-  return mseconds_left;
+-}
+-
+-
+ /**
+  * Complete the resume of a connection that has its own thread.
+  *
-- 
2.34.1

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

  parent reply	other threads:[~2026-10-21 12:52 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-26 13:36 [Buildroot] [PATCH] package/libmicrohttpd: fix build without thread support Yegor Yefremov via buildroot
2026-09-28  8:55 ` Thomas Petazzoni via buildroot
2026-09-28  9:08   ` Yegor Yefremov via buildroot
2026-09-28 10:05     ` Thomas Petazzoni via buildroot
2026-09-28 10:14       ` Yegor Yefremov via buildroot
2026-10-21 12:52 ` Yegor Yefremov via buildroot [this message]
2026-10-21 19:27   ` [Buildroot] [PATCH v2] " Thomas Petazzoni via buildroot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261021125214.141014-1-yegorslists@googlemail.com \
    --to=buildroot@buildroot.org \
    --cc=bernd@kuhls.net \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=will.newton@gmail.com \
    --cc=yegorslists@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox