libmicrohttpd2

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

commit 0fe26531aeb3c5900392eaf5adc3c03ce6f9fe7b
parent 7919626fb37cfcf57e5fa75f9c6835a13c610473
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Mon, 10 Aug 2026 17:54:08 +0200

mhd_atomic_counter: corrected, migrated to header-only

Diffstat:
Mconfigure.ac | 10++++------
Msrc/mhd2/Makefile.am | 2+-
Dsrc/mhd2/mhd_atomic_counter.c | 110-------------------------------------------------------------------------------
Msrc/mhd2/mhd_atomic_counter.h | 181+++++++++++++++++++++++++++++++++++++++++++------------------------------------
4 files changed, 103 insertions(+), 200 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -1948,7 +1948,9 @@ int main(void) natmc_var = atomic_fetch_xor_explicit(&atmc_var, natmc_var, memory_order_release); - return natmc_var + 1 - atomic_load_explicit(&atmc_var, memory_order_acquire); + atomic_thread_fence (memory_order_acquire); + + return natmc_var + 1 - atomic_load_explicit(&atmc_var, memory_order_relaxed); } ]] ) @@ -1984,11 +1986,6 @@ AS_VAR_IF([mhd_cv_c_atomic_variables],["yes"], #include <stdatomic.h> -#ifdef __STDC_NO_ATOMICS__ -#error __STDC_NO_ATOMICS__ is declared -fail test here %%%@<:@-1@:>@ -#endif - int main(void) { volatile _Atomic size_t cntr; @@ -1997,6 +1994,7 @@ int main(void) atomic_fetch_add_explicit(&cntr, 1, memory_order_relaxed); atomic_fetch_sub_explicit(&cntr, 1, memory_order_release); + atomic_thread_fence (memory_order_acquire); return (0u == atomic_load_explicit(&cntr, memory_order_relaxed)) ? diff --git a/src/mhd2/Makefile.am b/src/mhd2/Makefile.am @@ -42,7 +42,7 @@ libmicrohttpd2_la_SOURCES = \ mhd_socket_type.h mhd_sockets_macros.h \ mhd_sockets_funcs.c mhd_sockets_funcs.h \ mhd_socket_error_funcs.c mhd_socket_error_funcs.h mhd_socket_error.h \ - mhd_atomic_counter.c mhd_atomic_counter.h \ + mhd_atomic_counter.h \ mhd_bool.h \ mhd_str.c mhd_str.h \ mhd_rng.c mhd_rng.h \ diff --git a/src/mhd2/mhd_atomic_counter.c b/src/mhd2/mhd_atomic_counter.c @@ -1,110 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ -/* - This file is part of GNU libmicrohttpd. - Copyright (C) 2024-2025 Evgeny Grin (Karlson2k) - - GNU libmicrohttpd is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - GNU libmicrohttpd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - Alternatively, you can redistribute GNU libmicrohttpd and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version, together - with the eCos exception, as follows: - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile this - file and link it with other works to produce a work based on this - file, this file does not by itself cause the resulting work to be - covered by the GNU General Public License. However the source code - for this file must still be made available in accordance with - section (3) of the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - - You should have received copies of the GNU Lesser General Public - License and the GNU General Public License along with this library; - if not, see <https://www.gnu.org/licenses/>. -*/ - -/** - * @file src/mhd2/mhd_atomic_counter.c - * @brief The definition of the atomic counter functions - * @author Karlson2k (Evgeny Grin) - */ - -#include "mhd_sys_options.h" - -#include "mhd_atomic_counter.h" - -#if defined(mhd_ATOMIC_BY_LOCKS) - -# include "mhd_assert.h" - -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt) -{ - mhd_ATOMIC_COUNTER_TYPE ret; - - mhd_mutex_lock_chk (&(pcnt->lock)); - ret = pcnt->count++; - mhd_mutex_unlock_chk (&(pcnt->lock)); - - return ret; -} - - -# ifndef NDEBUG - -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) -{ - const mhd_ATOMIC_COUNTER_TYPE ret = mhd_atomic_counter_get_inc_wrap (pcnt); - - mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for overflow */ - - return ret; -} - - -# endif /* ! NDEBUG */ - - -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) -{ - mhd_ATOMIC_COUNTER_TYPE ret; - - mhd_mutex_lock_chk (&(pcnt->lock)); - ret = pcnt->count--; - mhd_mutex_unlock_chk (&(pcnt->lock)); - - mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for underflow */ - - return ret; -} - - -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt) -{ - mhd_ATOMIC_COUNTER_TYPE ret; - - mhd_mutex_lock_chk (&(pcnt->lock)); - ret = pcnt->count; - mhd_mutex_unlock_chk (&(pcnt->lock)); - - return ret; -} - - -#endif /* mhd_ATOMIC_BY_LOCKS */ diff --git a/src/mhd2/mhd_atomic_counter.h b/src/mhd2/mhd_atomic_counter.h @@ -137,6 +137,11 @@ struct mhd_AtomicCounter #endif /* mhd_ATOMIC_SINGLE_THREAD */ +#if defined(_MSC_FULL_VER) +# pragma warning(push) +/* Disable C4505 "unreferenced local function has been removed" */ +# pragma warning(disable:4505) +#endif /* _MSC_FULL_VER */ #if defined(mhd_ATOMIC_NATIVE) @@ -166,48 +171,25 @@ struct mhd_AtomicCounter */ # define mhd_atomic_counter_get_inc_wrap(pcnt) \ atomic_fetch_add_explicit (&((pcnt)->count), \ - 1, memory_order_relaxed) + 1u, memory_order_relaxed) -# ifdef NDEBUG /** * Atomically increment the value of the counter. * Counter overflow is detected in debug builds. * @param pcnt the pointer to the counter to increment */ -# define mhd_atomic_counter_inc(pcnt) \ - do { (void) \ - atomic_fetch_add_explicit (&((pcnt)->count), 1, \ +# ifdef NDEBUG +# define mhd_atomic_counter_inc(pcnt) \ + do { (void) \ + atomic_fetch_add_explicit (&((pcnt)->count), 1u, \ memory_order_relaxed); } while (0) - -/** - * Get the value of the counter and atomically increment the counter. - * Counter overflow is detected in debug builds. - * @param pcnt the pointer to the counter to increment - * @return the counter value before the increment - */ -# define mhd_atomic_counter_get_inc(pcnt) \ - mhd_atomic_counter_get_inc_wrap ((pcnt)) - -/** - * Get the value of the counter and atomically decrement the counter. - * Counter underflow is detected in debug builds. - * @param pcnt the pointer to the counter to decrement - * @return the counter value before the decrement - */ -# define mhd_atomic_counter_get_dec(pcnt) \ - atomic_fetch_sub_explicit (&((pcnt)->count), \ - 1, memory_order_release) # else /* _DEBUG */ -/** - * Atomically increment the value of the counter. - * Counter overflow is detected in debug builds. - * @param pcnt the pointer to the counter to increment - */ -# define mhd_atomic_counter_inc(pcnt) \ +# define mhd_atomic_counter_inc(pcnt) \ do { mhd_ATOMIC_COUNTER_TYPE old_val = \ - atomic_fetch_add_explicit (&((pcnt)->count), 1, \ + atomic_fetch_add_explicit (&((pcnt)->count), 1u, \ memory_order_relaxed); \ mhd_assert (mhd_ATOMIC_COUNTER_MAX != old_val); } while (0) +# endif /* _DEBUG */ /** * Get the value of the counter and atomically increment the counter. @@ -215,7 +197,11 @@ struct mhd_AtomicCounter * @param pcnt the pointer to the counter to increment * @return the counter value before the increment */ -mhd_static_inline mhd_ATOMIC_COUNTER_TYPE +# ifdef NDEBUG +# define mhd_atomic_counter_get_inc(pcnt) \ + mhd_atomic_counter_get_inc_wrap ((pcnt)) +# else /* _DEBUG */ +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) { mhd_ATOMIC_COUNTER_TYPE ret; @@ -228,27 +214,31 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) } +# endif /* _DEBUG */ + /** * Get the value of the counter and atomically decrement the counter. * Counter underflow is detected in debug builds. * @param pcnt the pointer to the counter to decrement * @return the counter value before the decrement */ -mhd_static_inline mhd_ATOMIC_COUNTER_TYPE +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) { mhd_ATOMIC_COUNTER_TYPE ret; - ret = atomic_fetch_sub_explicit (&((pcnt)->count), 1, memory_order_relaxed); + ret = atomic_fetch_sub_explicit (&((pcnt)->count), + 1u, + memory_order_release); + if (1u == ret) /* Sync with preceding releases when the last reference is dropped */ + atomic_thread_fence (memory_order_acquire); - mhd_assert (0 != ret); + mhd_assert (0u != ret); return ret; } -# endif /* _DEBUG */ - /** * Atomically get the value of the counter. * @param pcnt the pointer to the counter to get @@ -284,43 +274,37 @@ mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) * @param pcnt the pointer to the counter to increment * @return the counter value before the increment */ -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt); +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE +mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt) +{ + mhd_ATOMIC_COUNTER_TYPE ret; + + mhd_mutex_lock_chk (&(pcnt->lock)); + ret = pcnt->count++; + mhd_mutex_unlock_chk (&(pcnt->lock)); + + return ret; +} -# ifdef NDEBUG /** * Atomically increment the value of the counter. * Counter overflow is detected in debug builds. * @param pcnt the pointer to the counter to increment */ +# ifdef NDEBUG # define mhd_atomic_counter_inc(pcnt) do { \ mhd_mutex_lock_chk (&((pcnt)->lock)); \ ++((pcnt)->count); \ mhd_mutex_unlock_chk (&((pcnt)->lock)); } while (0) - -/** - * Get the value of the counter and atomically increment the counter. - * Counter overflow is detected in debug builds. - * @param pcnt the pointer to the counter to increment - * @return the counter value before the increment - */ -# define mhd_atomic_counter_get_inc(pcnt) \ - mhd_atomic_counter_get_inc_wrap (pcnt) - -# else - -/** - * Atomically increment the value of the counter. - * Counter overflow is detected in debug builds. - * @param pcnt the pointer to the counter to increment - */ +# else /* _DEBUG */ # define mhd_atomic_counter_inc(pcnt) do {\ mhd_ATOMIC_COUNTER_TYPE old_val; \ mhd_mutex_lock_chk (&((pcnt)->lock)); \ old_val = (pcnt)->count++; \ mhd_mutex_unlock_chk (&((pcnt)->lock)); \ mhd_assert (mhd_ATOMIC_COUNTER_MAX != old_val); } while (0) +# endif /* _DEBUG */ /** * Get the value of the counter and atomically increment the counter. @@ -328,10 +312,23 @@ mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt); * @param pcnt the pointer to the counter to increment * @return the counter value before the increment */ -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt); +# ifdef NDEBUG +# define mhd_atomic_counter_get_inc(pcnt) \ + mhd_atomic_counter_get_inc_wrap ((pcnt)) + +# else /* _DEBUG */ +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE +mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) +{ + const mhd_ATOMIC_COUNTER_TYPE ret = mhd_atomic_counter_get_inc_wrap (pcnt); + + mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for overflow */ + + return ret; +} -# endif + +# endif /* _DEBUG */ /** * Get the value of the counter and atomically decrement the counter. @@ -339,16 +336,38 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt); * @param pcnt the pointer to the counter to decrement * @return the counter value before the decrement */ -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt); +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE +mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) +{ + mhd_ATOMIC_COUNTER_TYPE ret; + + mhd_mutex_lock_chk (&(pcnt->lock)); + ret = pcnt->count--; + mhd_mutex_unlock_chk (&(pcnt->lock)); + + mhd_assert (0u != ret); /* check for underflow */ + + return ret; +} + /** * Atomically get the value of the counter. * @param pcnt the pointer to the counter to get * @return the counter value */ -MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE -mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt); +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE +mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt) +{ + mhd_ATOMIC_COUNTER_TYPE ret; + + mhd_mutex_lock_chk (&(pcnt->lock)); + ret = pcnt->count; + mhd_mutex_unlock_chk (&(pcnt->lock)); + + return ret; +} + #elif defined(mhd_ATOMIC_SINGLE_THREAD) @@ -387,32 +406,17 @@ mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt); do { mhd_assert (mhd_ATOMIC_COUNTER_MAX != ((pcnt)->count)); \ ++((pcnt)->count); } while (0) -# ifdef NDEBUG /** * Get the value of the counter and atomically increment the counter. * Counter overflow is detected in debug builds. * @param pcnt the pointer to the counter to increment * @return the counter value before the increment */ +# ifdef NDEBUG # define mhd_atomic_counter_get_inc(pcnt) \ mhd_atomic_counter_get_inc_wrap ((pcnt)) - -/** - * Get the value of the counter and atomically decrement the counter. - * Counter underflow is detected in debug builds. - * @param pcnt the pointer to the counter to decrement - * @return the counter value before the decrement - */ -# define mhd_atomic_counter_get_dec(pcnt) ((pcnt)->count--) - # else /* _DEBUG */ -/** - * Get the value of the counter and atomically increment the counter. - * Counter overflow is detected in debug builds. - * @param pcnt the pointer to the counter to increment - * @return the counter value before the increment - */ -mhd_static_inline mhd_ATOMIC_COUNTER_TYPE +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) { mhd_assert (mhd_ATOMIC_COUNTER_MAX != (pcnt->count)); @@ -421,16 +425,21 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt) } +# endif /* _DEBUG */ + /** * Get the value of the counter and atomically decrement the counter. * Counter underflow is detected in debug builds. * @param pcnt the pointer to the counter to decrement * @return the counter value before the decrement */ -mhd_static_inline mhd_ATOMIC_COUNTER_TYPE +# ifdef NDEBUG +# define mhd_atomic_counter_get_dec(pcnt) ((pcnt)->count--) +# else /* _DEBUG */ +mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) { - mhd_assert (0 != ((pcnt)->count)); + mhd_assert (0u != ((pcnt)->count)); return ((pcnt)->count--); } @@ -447,4 +456,10 @@ mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt) #endif /* mhd_ATOMIC_SINGLE_THREAD */ + +#if defined(_MSC_FULL_VER) +/* Restore warnings */ +# pragma warning(pop) +#endif /* _MSC_FULL_VER */ + #endif /* ! MHD_ATOMIC_COUNTER_H */