commit 0ca55b1a26c99a30dca5596063367fb92bd4f05e
parent 86364f6ac82e5293a6eaf354910e464cd64b7efa
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Wed, 5 Aug 2026 16:42:17 +0200
mhd_locks.h: updated, improved and fixed
Added better macros to catch any duplicated implementations.
Removed duplicated comments to improve readability.
Added support for error-checking mutex in debug builds.
Removed extra '\n' in panic messages.
Diffstat:
| M | src/mhd2/mhd_locks.h | | | 193 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
1 file changed, 88 insertions(+), 105 deletions(-)
diff --git a/src/mhd2/mhd_locks.h b/src/mhd2/mhd_locks.h
@@ -1,7 +1,7 @@
/* 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) 2016-2025 Evgeny Grin (Karlson2k)
+ Copyright (C) 2016-2026 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
@@ -63,22 +63,29 @@
/**
* The mutex is POSIX Threads' mutex
*/
-# define mhd_MUTEX_KIND_PTHREAD 1
+# define mhd_MUTEX_KIND_PTHREAD 1
+# define mhd_MUTEX_IMPLEMENTED 1
# include <pthread.h>
# include "sys_null_macro.h"
-# elif defined(mhd_THREADS_KIND_W32)
+# endif
+
+# if !defined(mhd_MUTEX_IMPLEMENTED) && defined(mhd_THREADS_KIND_W32)
# include "sys_w32_ver.h"
+/* Define MHD_NO_W32_SRWLOCKS_MUTEX to force use critical section on W32 */
# if _WIN32_WINNT >= 0x0600 /* Vista or later */ && \
- !defined(MHD_NO_W32_SRWLOCKS)
+ !defined(MHD_NO_W32_SRWLOCKS_MUTEX)
/**
* The mutex is W32 SRW lock
*/
-# define mhd_MUTEX_KIND_W32_SRW 1
-# else
+# define mhd_MUTEX_KIND_W32_SRW 1
+# define mhd_MUTEX_IMPLEMENTED 1
+# endif
+# ifndef mhd_MUTEX_IMPLEMENTED
/**
* The mutex is W32 Critical Section
*/
-# define mhd_MUTEX_KIND_W32_CS 1
+# define mhd_MUTEX_KIND_W32_CS 1
+# define mhd_MUTEX_IMPLEMENTED 1
# endif
# if 0 /* _WIN32_WINNT >= 0x0602 */ /* Win8 or later */
/* This include does not work as _ARM_ or _AMD64_ macros
@@ -87,10 +94,39 @@
# else
# include <windows.h>
# endif
-# else
+# endif
+
+# ifndef mhd_MUTEX_IMPLEMENTED
# error No base mutex API is available.
# endif
+/* Sanity check */
+# ifdef mhd_MUTEX_KIND_PTHREAD
+# ifndef mhd_MUTEX_HAS_ONE_IMPLEMENTATION
+# define mhd_MUTEX_HAS_ONE_IMPLEMENTATION 1
+# else
+# error Multiple mutex implementations are enabled simultaneously
+# endif
+# endif
+# ifdef mhd_MUTEX_KIND_W32_SRW
+# ifndef mhd_MUTEX_HAS_ONE_IMPLEMENTATION
+# define mhd_MUTEX_HAS_ONE_IMPLEMENTATION 1
+# else
+# error Multiple mutex implementations are enabled simultaneously
+# endif
+# endif
+# ifdef mhd_MUTEX_KIND_W32_CS
+# ifndef mhd_MUTEX_HAS_ONE_IMPLEMENTATION
+# define mhd_MUTEX_HAS_ONE_IMPLEMENTATION 1
+# else
+# error Multiple mutex implementations are enabled simultaneously
+# endif
+# endif
+# ifndef mhd_MUTEX_HAS_ONE_IMPLEMENTATION
+# error Not all mutex kinds were checked
+# endif
+# undef mhd_MUTEX_HAS_ONE_IMPLEMENTATION
+
# include "mhd_panic.h"
# if defined(mhd_MUTEX_KIND_PTHREAD)
@@ -101,45 +137,29 @@ typedef SRWLOCK mhd_mutex;
typedef CRITICAL_SECTION mhd_mutex;
# endif
-# if defined(mhd_MUTEX_KIND_PTHREAD)
/**
* Initialise a new mutex.
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_init(pmutex) (0 == pthread_mutex_init ((pmutex), NULL))
+# if defined(mhd_MUTEX_KIND_PTHREAD)
+# define mhd_mutex_init(pmutex) (0 == pthread_mutex_init((pmutex), NULL))
# elif defined(mhd_MUTEX_KIND_W32_SRW)
-/**
- * Initialise a new mutex.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_init(pmutex) (InitializeSRWLock ((pmutex)), ! 0)
+# define mhd_mutex_init(pmutex) (InitializeSRWLock((pmutex)), ! 0)
# elif defined(mhd_MUTEX_KIND_W32_CS)
# if _WIN32_WINNT < 0x0600
/* Before Vista */
-/**
- * Initialise a new mutex.
- * @param pmutex the pointer to the mutex
- * @return nonzero on success, zero otherwise
- */
# define mhd_mutex_init(pmutex) \
- (InitializeCriticalSectionAndSpinCount ((pmutex), 0))
+ (InitializeCriticalSectionAndSpinCount((pmutex), 0))
# else
/* The function always succeed starting from Vista */
-/**
- * Initialise a new mutex.
- * @param pmutex the pointer to the mutex
- * @return nonzero on success, zero otherwise
- */
# define mhd_mutex_init(pmutex) \
- (((void) InitializeCriticalSection (pmutex)), ! 0)
+ (((void) InitializeCriticalSection(pmutex)), ! 0)
# endif
+# else
+# error Mutex implementation is missing
# endif
-# ifdef mhd_MUTEX_KIND_W32_CS
-# if _WIN32_WINNT < 0x0600
-/* Before Vista */
/**
* Initialise a new mutex for short locks.
*
@@ -150,22 +170,15 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
+# ifdef mhd_MUTEX_KIND_W32_CS
+# if _WIN32_WINNT < 0x0600
+/* Before Vista */
# define mhd_mutex_init_short(pmutex) \
- (InitializeCriticalSectionAndSpinCount ((pmutex), 128))
+ (InitializeCriticalSectionAndSpinCount((pmutex), 128))
# else
/* The function always succeed starting from Vista */
-/**
- * Initialise a new mutex for short locks.
- *
- * Initialised mutex is optimised for locks held only for very short period of
- * time. It should be used when only a single or just a few variables are
- * modified under the lock.
- *
- * @param pmutex the pointer to the mutex
- * @return nonzero on success, zero otherwise
- */
# define mhd_mutex_init_short(pmutex) \
- ((void) InitializeCriticalSectionAndSpinCount ((pmutex), 128), ! 0)
+ ((void) InitializeCriticalSectionAndSpinCount((pmutex), 128), ! 0)
# endif
# endif
@@ -173,18 +186,18 @@ typedef CRITICAL_SECTION mhd_mutex;
# define mhd_mutex_init_short(pmutex) mhd_mutex_init ((pmutex))
# endif
-# if defined(mhd_MUTEX_KIND_PTHREAD)
-# if defined(PTHREAD_MUTEX_INITIALIZER)
/**
* The value to statically initialise mutex
*/
+# if defined(mhd_MUTEX_KIND_PTHREAD)
+# if !defined(NDEBUG) && defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
+# define mhd_MUTEX_INITIALISER_STAT \
+ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+# elif defined(PTHREAD_MUTEX_INITIALIZER)
# define mhd_MUTEX_INITIALISER_STAT PTHREAD_MUTEX_INITIALIZER
-# endif /* PTHREAD_MUTEX_INITIALIZER */
+# endif
# elif defined(mhd_MUTEX_KIND_W32_SRW)
# if defined(SRWLOCK_INIT)
-/**
- * The value to statically initialise mutex
- */
# define mhd_MUTEX_INITIALISER_STAT SRWLOCK_INIT
# endif
# endif
@@ -197,31 +210,22 @@ typedef CRITICAL_SECTION mhd_mutex;
static mhd_mutex m = mhd_MUTEX_INITIALISER_STAT
# endif
-# if defined(mhd_MUTEX_KIND_PTHREAD)
/**
* Destroy previously initialised mutex.
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_destroy(pmutex) (0 == pthread_mutex_destroy ((pmutex)))
+# if defined(mhd_MUTEX_KIND_PTHREAD)
+# define mhd_mutex_destroy(pmutex) (0 == pthread_mutex_destroy((pmutex)))
# elif defined(mhd_MUTEX_KIND_W32_SRW)
-/**
- * Destroy (no-op) previously initialised mutex.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
# define mhd_mutex_destroy(pmutex) ((void) (pmutex), ! 0)
# elif defined(mhd_MUTEX_KIND_W32_CS)
-/**
- * Destroy previously initialised mutex.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_destroy(pmutex) (DeleteCriticalSection ((pmutex)), ! 0)
+# define mhd_mutex_destroy(pmutex) (DeleteCriticalSection((pmutex)), ! 0)
+# else
+# error Mutex implementation is missing
# endif
-# if defined(mhd_MUTEX_KIND_PTHREAD)
/**
* Acquire a lock on previously initialised mutex.
* If the mutex was already locked by other thread, function blocks until
@@ -229,50 +233,29 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_lock(pmutex) (0 == pthread_mutex_lock ((pmutex)))
+# if defined(mhd_MUTEX_KIND_PTHREAD)
+# define mhd_mutex_lock(pmutex) (0 == pthread_mutex_lock((pmutex)))
# elif defined(mhd_MUTEX_KIND_W32_SRW)
-/**
- * Acquire a lock on previously initialised mutex.
- * If the mutex was already locked by other thread, function blocks until
- * the mutex becomes available.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_lock(pmutex) (AcquireSRWLockExclusive ((pmutex)), ! 0)
+# define mhd_mutex_lock(pmutex) (AcquireSRWLockExclusive((pmutex)), ! 0)
# elif defined(mhd_MUTEX_KIND_W32_CS)
-/**
- * Acquire a lock on previously initialised mutex.
- * If the mutex was already locked by other thread, function blocks until
- * the mutex becomes available.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_lock(pmutex) (EnterCriticalSection ((pmutex)), ! 0)
+# define mhd_mutex_lock(pmutex) (EnterCriticalSection((pmutex)), ! 0)
+# else
+# error Mutex implementation is missing
# endif
-# if defined(mhd_MUTEX_KIND_PTHREAD)
/**
* Unlock previously locked mutex.
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_unlock(pmutex) (0 == pthread_mutex_unlock ((pmutex)))
+# if defined(mhd_MUTEX_KIND_PTHREAD)
+# define mhd_mutex_unlock(pmutex) (0 == pthread_mutex_unlock((pmutex)))
# elif defined(mhd_MUTEX_KIND_W32_SRW)
-/**
- * Acquire a lock on previously initialised mutex.
- * If the mutex was already locked by other thread, function blocks until
- * the mutex becomes available.
- * @param pmutex the pointer to the mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_unlock(pmutex) (ReleaseSRWLockExclusive ((pmutex)), ! 0)
+# define mhd_mutex_unlock(pmutex) (ReleaseSRWLockExclusive((pmutex)), ! 0)
# elif defined(mhd_MUTEX_KIND_W32_CS)
-/**
- * Unlock previously initialised and locked mutex.
- * @param pmutex pointer to mutex
- * @return always nonzero (success)
- */
-# define mhd_mutex_unlock(pmutex) (LeaveCriticalSection ((pmutex)), ! 0)
+# define mhd_mutex_unlock(pmutex) (LeaveCriticalSection((pmutex)), ! 0)
+# else
+# error Mutex implementation is missing
# endif
/**
@@ -280,9 +263,9 @@ typedef CRITICAL_SECTION mhd_mutex;
* detected.
* @param pmutex the pointer to the mutex
*/
-# define mhd_mutex_destroy_chk(pmutex) do { \
- if (! mhd_mutex_destroy (pmutex)) \
- MHD_PANIC ("Failed to destroy mutex.\n"); \
+# define mhd_mutex_destroy_chk(pmutex) do { \
+ if (! mhd_mutex_destroy((pmutex))) \
+ MHD_PANIC ("Failed to destroy mutex."); \
} while (0)
/**
@@ -292,9 +275,9 @@ typedef CRITICAL_SECTION mhd_mutex;
* If error is detected, execution is aborted.
* @param pmutex the pointer to the mutex
*/
-# define mhd_mutex_lock_chk(pmutex) do { \
- if (! mhd_mutex_lock (pmutex)) \
- MHD_PANIC ("Failed to lock mutex.\n"); \
+# define mhd_mutex_lock_chk(pmutex) do { \
+ if (! mhd_mutex_lock((pmutex))) \
+ MHD_PANIC ("Failed to lock mutex."); \
} while (0)
/**
@@ -302,9 +285,9 @@ typedef CRITICAL_SECTION mhd_mutex;
* If error is detected, execution is aborted.
* @param pmutex the pointer to the mutex
*/
-# define mhd_mutex_unlock_chk(pmutex) do { \
- if (! mhd_mutex_unlock (pmutex)) \
- MHD_PANIC ("Failed to unlock mutex.\n"); \
+# define mhd_mutex_unlock_chk(pmutex) do { \
+ if (! mhd_mutex_unlock((pmutex))) \
+ MHD_PANIC ("Failed to unlock mutex."); \
} while (0)
#else /* ! MHD_SUPPORT_THREADS */