libmicrohttpd2

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

commit 69729650b88f8d456183022d7502c7af26acfdba
parent 05ddd5470cb44434b99125f300065f7601e1feab
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Sat, 14 Feb 2026 23:14:24 +0100

mhd_dlinked_list.h: improved comments, replaced asserts with "assume"

Diffstat:
Msrc/mhd2/mhd_dlinked_list.h | 239+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 123 insertions(+), 116 deletions(-)

diff --git a/src/mhd2/mhd_dlinked_list.h b/src/mhd2/mhd_dlinked_list.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) 2024-2025 Evgeny Grin (Karlson2k) + Copyright (C) 2024-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 @@ -42,8 +42,8 @@ * @author Karlson2k (Evgeny Grin) * * Doubly-linked list macros help create and manage the chain of objects - * connected via inter-object pointers (named here @a links_name), while - * the list is held by the owner within the helper (named here @a list_name). + * connected via inter-link pointers (named here @a links_name), while + * the list is held by the owner in the helper struct (named here @a list_name). */ #ifndef MHD_DLINKED_LIST_H @@ -52,25 +52,27 @@ #include "mhd_sys_options.h" #include "sys_null_macro.h" -#include "mhd_assert.h" #include "mhd_assume.h" -/* This header defines macros for handling doubly-linked lists of objects. - The pointers to the first and the last objects in the list are held in - the "owner". - The list member object links to each other via "next" and "prev" links. - Each member object can be part of several lists. For example, connections are - maintained in "all connections" and "need to process" lists simultaneously. - List member can be removed from the list or inserted to the list at any - moment. - Typically the name of the list (inside the "owner" object) is the same as - the name of inter-links. However, it is possible to use different names. - For example, connections can be removed from "all connections" list and - moved the "clean up" list using the same internal links "all connections". - As this is a doubly-linked list, it can be walked rom the beginning to the - end and in the opposite direction. - The list is designed to work with struct tags as a contained and container +/* This header defines macros for handling doubly-linked lists of objects + (list elements). The pointers to the first and the last elements in the + list are held in the list "owner". + The list elements connect to each other via "next" and "prev" inter-links. + Each element can be part of several lists at the same time, if referenced + by differently named fields with inter-links. For example, connections are + maintained in "all connections" and "need to be processed" lists + simultaneously. + A list element can be removed from the list (if it is already in the list) + or inserted into the list (if it is NOT in the list) at any moment. + Typically the name of the list (the field inside the "owner" object) is + the same as the name of field with inter-links. However, it is possible to + use different names. For example, connections can be removed from "all + connections" list and moved to the "clean up" list using the same internal + inter-links field "all connections". + As this is a doubly-linked list, it can be walked from the beginning to + the end and in the opposite direction. + The list is designed to work with struct tags as contained and container objects. */ @@ -84,66 +86,69 @@ /* Names */ /** - * The name of struct that holds the list in the owner object + * The name of the struct (struct tag) that holds the list in the owner object */ #define mhd_DLNKDL_LIST_TYPE(base_name) mhd_DLNKDL_LIST_TYPE_ (base_name) /** - * The name of the struct that holds the links between list members + * The name of the struct (struct tag) that holds the inter-links between list + * elements */ #define mhd_DLNKDL_LINKS_TYPE(base_name) mhd_DLNKDL_LINKS_TYPE_ (base_name) + /* Definitions of the structures */ /** * Template for declaration of the list helper struct - * @param l_type the struct tag name of objects that list links + * @param l_type the struct tag name of elements that the list holds */ #define mhd_DLINKEDL_LIST_DEF(l_type) \ mhd_DLNKDL_LIST_TYPE (l_type) { /* Holds the list in the owner */ \ - struct l_type *first; /* The pointer to the first object in the list */ \ - struct l_type *last; /* The pointer to the last object in the list */ \ + struct l_type *first; /* The pointer to the first element in the list */ \ + struct l_type *last; /* The pointer to the last element in the list */ \ } /** - * Template for declaration of links helper struct - * @param l_type the struct tag name of objects that list links + * Template for declaration of the inter-links helper struct + * @param l_type the struct tag name of elements linked by the inter-links */ #define mhd_DLINKEDL_LINKS_DEF(l_type) \ - mhd_DLNKDL_LINKS_TYPE (l_type) { /* Holds the links in the members */ \ - struct l_type *prev; /* The pointer to the previous object in the list */ \ - struct l_type *next; /* The pointer to the next object in the list */ \ + /* Holds the inter-links in the list element */ \ + mhd_DLNKDL_LINKS_TYPE (l_type) { \ + struct l_type *prev; /* The pointer to the previous element in the list */ \ + struct l_type *next; /* The pointer to the next element in the list */ \ } - /** - * Template for declaration of list helper structs - * @param l_type the struct tag name of objects that the list holds + * Template for declaration of the list helper structs + * @param l_type the struct tag name of elements that the list holds */ #define mhd_DLINKEDL_STRUCTS_DEFS(l_type) \ mhd_DLINKEDL_LIST_DEF (l_type); mhd_DLINKEDL_LINKS_DEF (l_type) -/* Declarations for the list owners and the list members */ + +/* Declarations of the types for the list owners and the list elements */ /** - * Declare the owner's list member + * Declare the list field in the owner struct */ #define mhd_DLNKDL_LIST(l_type,list_name) \ mhd_DLNKDL_LIST_TYPE (l_type) list_name /** - * Declare the list object links member + * Declare the inter-links field in the list element */ #define mhd_DLNKDL_LINKS(l_type,links_name) \ mhd_DLNKDL_LINKS_TYPE (l_type) links_name /* Direct work with the list */ /* These macros directly use the pointer to the list and allow using - * names of the list object (within the owner object) different from the names - * of link object (in the list members). */ + * names of the list field (within the owner object) different from the + * names of the inter-links field (in the list elements). */ /** - * Initialise the doubly linked list pointers in the list object using + * Initialise the doubly linked list pointers in the list owner using * the direct pointer to the list * @warning arguments are evaluated multiple times * @param p_list the pointer to the list @@ -152,107 +157,110 @@ do {(p_list)->first = NULL; (p_list)->last = NULL;} while (0) /** - * Insert object into the first position in the list using direct pointer - * to the list + * Insert new list element into the first position in the list using direct + * pointer to the list * @warning arguments are evaluated multiple times * @param p_list the pointer to the list - * @param p_obj the pointer to the new list member object to insert to - * the @a links_name list - * @param links_name the name of the links member in the @a p_obj + * @param p_obj the pointer to the new element to insert into the list, + * using @a links_name inter-links + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_INS_FIRST_D(p_list,p_obj,links_name) do { \ - mhd_assert (NULL == (p_obj)->links_name.prev); \ - mhd_assert (NULL == (p_obj)->links_name.next); \ - mhd_assert ((p_obj) != (p_list)->first); \ - mhd_assert ((p_obj) != (p_list)->last); \ + mhd_ASSUME (NULL == (p_obj)->links_name.prev); \ + mhd_ASSUME (NULL == (p_obj)->links_name.next); \ + mhd_ASSUME ((p_obj) != (p_list)->first); \ + mhd_ASSUME ((p_obj) != (p_list)->last); \ if (NULL != (p_list)->first) \ - { mhd_assert (NULL == (p_list)->first->links_name.prev); \ - mhd_assert (NULL == (p_list)->last->links_name.next); \ - mhd_assert ((p_obj) != (p_list)->first->links_name.next); \ - mhd_assert (NULL != (p_list)->last); \ + { mhd_ASSUME (NULL == (p_list)->first->links_name.prev); \ + mhd_ASSUME (NULL == (p_list)->last->links_name.next); \ + mhd_ASSUME ((p_obj) != (p_list)->first->links_name.next); \ + mhd_ASSUME (NULL != (p_list)->last); \ ((p_obj)->links_name.next = (p_list)->first) \ ->links_name.prev = (p_obj); } else \ - { mhd_assert (NULL == (p_list)->last); \ + { mhd_ASSUME (NULL == (p_list)->last); \ (p_list)->last = (p_obj); } \ (p_list)->first = (p_obj); } while (0) /** - * Insert object into the last position in the list using direct pointer - * to the list + * Insert new list element into the last position in the list using direct + * pointer to the list * @warning arguments are evaluated multiple times * @param p_list the pointer to the list - * @param p_obj the pointer to the new list member object to insert to - * the @a links_name list - * @param links_name the name of the links member in the @a p_obj + * @param p_obj the pointer to the new element to insert into the list, + * using @a links_name inter-links + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_INS_LAST_D(p_list,p_obj,links_name) do { \ - mhd_assert (NULL == (p_obj)->links_name.prev); \ - mhd_assert (NULL == (p_obj)->links_name.next); \ - mhd_assert ((p_obj) != (p_list)->first); \ - mhd_assert ((p_obj) != (p_list)->last); \ + mhd_ASSUME (NULL == (p_obj)->links_name.prev); \ + mhd_ASSUME (NULL == (p_obj)->links_name.next); \ + mhd_ASSUME ((p_obj) != (p_list)->first); \ + mhd_ASSUME ((p_obj) != (p_list)->last); \ if (NULL != (p_list)->last) \ - { mhd_assert (NULL == (p_list)->last->links_name.next); \ - mhd_assert (NULL == (p_list)->first->links_name.prev); \ - mhd_assert ((p_obj) != (p_list)->last->links_name.prev); \ - mhd_assert (NULL != (p_list)->first); \ + { mhd_ASSUME (NULL == (p_list)->last->links_name.next); \ + mhd_ASSUME (NULL == (p_list)->first->links_name.prev); \ + mhd_ASSUME ((p_obj) != (p_list)->last->links_name.prev); \ + mhd_ASSUME (NULL != (p_list)->first); \ ((p_obj)->links_name.prev = (p_list)->last) \ ->links_name.next = (p_obj); } else \ - { mhd_assert (NULL == (p_list)->first); \ + { mhd_ASSUME (NULL == (p_list)->first); \ (p_list)->first = (p_obj); } \ (p_list)->last = (p_obj); } while (0) /** - * Remove object from the list using direct pointer to the list + * Remove list element from the list using direct pointer to the list * @warning arguments are evaluated multiple times * @param p_list the pointer to the list - * @param p_obj the pointer to the existing list member object - * to remove from the list - * @param links_name the name of the links member in the @a p_obj + * @param p_obj the pointer to the existing list element to remove from the list + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_DEL_D(p_list,p_obj,links_name) do { \ - mhd_assert (NULL != (p_list)->first); \ - mhd_assert (NULL != (p_list)->last); \ - mhd_assert (NULL == (p_list)->first->links_name.prev); \ - mhd_assert (NULL == (p_list)->last->links_name.next); \ - mhd_assert ((p_obj) != (p_obj)->links_name.prev); \ - mhd_assert ((p_list)->last != (p_obj)->links_name.prev); \ - mhd_assert ((p_obj) != (p_obj)->links_name.next); \ - mhd_assert ((p_list)->first != (p_obj)->links_name.next); \ + mhd_ASSUME (NULL != (p_list)->first); \ + mhd_ASSUME (NULL != (p_list)->last); \ + mhd_ASSUME (NULL == (p_list)->first->links_name.prev); \ + mhd_ASSUME (NULL == (p_list)->last->links_name.next); \ + mhd_ASSUME ((p_obj) != (p_obj)->links_name.prev); \ + mhd_ASSUME ((p_list)->last != (p_obj)->links_name.prev); \ + mhd_ASSUME ((p_obj) != (p_obj)->links_name.next); \ + mhd_ASSUME ((p_list)->first != (p_obj)->links_name.next); \ if (NULL != (p_obj)->links_name.next) \ - { mhd_assert ((p_obj) == (p_obj)->links_name.next->links_name.prev); \ - mhd_assert ((p_obj) != (p_list)->last); \ + { mhd_ASSUME ((p_obj) == (p_obj)->links_name.next->links_name.prev); \ + mhd_ASSUME ((p_obj) != (p_list)->last); \ + mhd_ASSUME ((p_obj)->links_name.next != \ + (p_obj)->links_name.prev); \ (p_obj)->links_name.next->links_name.prev = \ (p_obj)->links_name.prev; } else \ - { mhd_assert ((p_obj) == (p_list)->last); \ + { mhd_ASSUME ((p_obj) == (p_list)->last); \ (p_list)->last = (p_obj)->links_name.prev; } \ if (NULL != (p_obj)->links_name.prev) \ - { mhd_assert ((p_obj) == (p_obj)->links_name.prev->links_name.next); \ - mhd_assert ((p_obj) != (p_list)->first); \ + { mhd_ASSUME ((p_obj) == (p_obj)->links_name.prev->links_name.next); \ + mhd_ASSUME ((p_obj) != (p_list)->first); \ + mhd_ASSUME ((p_obj)->links_name.next != \ + (p_obj)->links_name.prev); \ (p_obj)->links_name.prev->links_name.next = \ (p_obj)->links_name.next; } else \ - { mhd_assert ((p_obj) == (p_list)->first); \ + { mhd_ASSUME ((p_obj) == (p_list)->first); \ (p_list)->first = (p_obj)->links_name.next; } \ (p_obj)->links_name.prev = NULL; \ (p_obj)->links_name.next = NULL; } while (0) /** - * Get the first object in the list using direct pointer to the list + * Get the first element in the list using direct pointer to the list */ #define mhd_DLINKEDL_GET_FIRST_D(p_list) ((p_list)->first) /** - * Get the last object in the list using direct pointer to the list + * Get the last element in the list using direct pointer to the list */ #define mhd_DLINKEDL_GET_LAST_D(p_list) ((p_list)->last) /** - * Move the object within the list to the first position using a direct pointer - * to the list + * Move the list element within the list to the first position using a direct + * pointer to the list * @warning arguments are evaluated multiple times * @param p_list the pointer to the list - * @param p_obj the pointer to the existing list member object to move to the + * @param p_obj the pointer to the existing list element to move to the * first position - * @param links_name the name of the links member in the @a p_obj + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_MOVE_TO_FIRST_D(p_list,p_obj,links_name) do { \ mhd_ASSUME (NULL != (p_list)->first); \ @@ -281,8 +289,8 @@ /* ** The main interface ** */ -/* These macros use identical names for the list object itself (within the - * owner object) and the links object (within the list members). */ +/* These macros use identical names for the list field (within the owner + * object) and the inter-links field (within the list elements). */ /* Initialisers */ @@ -296,11 +304,11 @@ mhd_DLINKEDL_INIT_LIST_D (&((p_own)->list_name)) /** - * Initialise the doubly linked list pointers in the list member object + * Initialise the doubly linked list pointers in the list element * @warning arguments are evaluated multiple times - * @param p_obj the pointer to the future member object of + * @param p_obj the pointer to the future element of * the @a links_name list - * @param links_name the name of the links member in the @a p_obj + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_INIT_LINKS(p_obj,links_name) \ do {(p_obj)->links_name.prev = NULL; \ @@ -309,34 +317,37 @@ /* List manipulations */ /** - * Insert object into the first position in the list + * Insert new list element into the first position in the list * @warning arguments are evaluated multiple times * @param p_own the pointer to the owner object with the @a l_name list - * @param p_obj the pointer to the new list member object to insert to + * @param p_obj the pointer to the new list element to insert into * the @a l_name list - * @param l_name the same name for the list and the links + * @param l_name the same name for the list field in the owner and + * the inter-links field in the list element */ #define mhd_DLINKEDL_INS_FIRST(p_own,p_obj,l_name) \ mhd_DLINKEDL_INS_FIRST_D (&((p_own)->l_name),(p_obj),l_name) /** - * Insert object into the last position in the list + * Insert new list element into the last position in the list * @warning arguments are evaluated multiple times * @param p_own the pointer to the owner object with the @a l_name list - * @param p_obj the pointer to the new list member object to insert to + * @param p_obj the pointer to the new list element to insert into * the @a l_name list - * @param l_name the same name for the list and the links + * @param l_name the same name for the list field in the owner and + * the inter-links field in the list element */ #define mhd_DLINKEDL_INS_LAST(p_own,p_obj,l_name) \ mhd_DLINKEDL_INS_LAST_D (&((p_own)->l_name),(p_obj),l_name) /** - * Remove object from the list + * Remove list element from the list * @warning arguments are evaluated multiple times * @param p_own the pointer to the owner object with the @a l_name list - * @param p_obj the pointer to the existing @a l_name list member object + * @param p_obj the pointer to the existing @a l_name list element * to remove from the list - * @param l_name the same name for the list and the links + * @param l_name the same name for the list field in the owner and + * the inter-links field in the list element */ #define mhd_DLINKEDL_DEL(p_own,p_obj,l_name) \ mhd_DLINKEDL_DEL_D (&((p_own)->l_name),(p_obj),l_name) @@ -344,8 +355,7 @@ /* List iterations */ /** - * Get the first object in the list - * @warning arguments are evaluated multiple times + * Get the first element in the list * @param p_own the pointer to the owner object with the @a list_name list * @param list_name the name of the list */ @@ -353,8 +363,7 @@ mhd_DLINKEDL_GET_FIRST_D (&((p_own)->list_name)) /** - * Get the last object in the list - * @warning arguments are evaluated multiple times + * Get the last element in the list * @param p_own the pointer to the owner object with the @a list_name list * @param list_name the name of the list */ @@ -362,18 +371,16 @@ mhd_DLINKEDL_GET_LAST_D (&((p_own)->list_name)) /** - * Get the next object in the list - * @warning arguments are evaluated multiple times - * @param p_obj the pointer to the existing @a links_name list member object - * @param links_name the name of the links member in the @a p_obj + * Get the next element in the list + * @param p_obj the pointer to the existing @a links_name list element + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_GET_NEXT(p_obj,links_name) ((p_obj)->links_name.next) /** - * Get the previous object in the list - * @warning arguments are evaluated multiple times - * @param p_obj the pointer to the existing @a links_name list member object - * @param links_name the name of the links member in the @a p_obj + * Get the previous element in the list + * @param p_obj the pointer to the existing @a links_name list element + * @param links_name the name of the inter-links field in the @a p_obj */ #define mhd_DLINKEDL_GET_PREV(p_obj,links_name) ((p_obj)->links_name.prev)