X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=include%2Fldap_queue.h;h=34588478372d87840a773a5f1eb323f5bee10a15;hb=HEAD;hp=13ce86a7d2910db54b134a44919db07c8fec64d9;hpb=1add666e5a6ace4281df809ad5d37c4534333616;p=openldap diff --git a/include/ldap_queue.h b/include/ldap_queue.h index 13ce86a7d2..3458847837 100644 --- a/include/ldap_queue.h +++ b/include/ldap_queue.h @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2001-2015 The OpenLDAP Foundation. + * Copyright 2001-2018 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,7 +102,9 @@ * traverse the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the list. * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. + * complex end of list detection. Also, it is possible to rotate the queue, + * rejoining the ends and splitting it so that a given element becomes the + * new head or tail. * * For details on the use of these macros, see the queue(3) manual page. * All macros are prefixed with LDAP_. @@ -225,7 +227,7 @@ struct { \ } while (0) #define LDAP_STAILQ_ENTRY_INIT(var, field) { \ - (entry)->field.stqe_next = NULL; \ + (var)->field.stqe_next = NULL; \ } #define LDAP_STAILQ_FIRST(head) ((head)->stqh_first) @@ -384,26 +386,20 @@ struct { \ #define LDAP_TAILQ_FOREACH(var, head, field) \ for (var = LDAP_TAILQ_FIRST(head); var; var = LDAP_TAILQ_NEXT(var, field)) -#define LDAP_TAILQ_FOREACH_REVERSE(var, head, type, field) \ - for ((var) = LDAP_TAILQ_LAST((head), type, field); \ +#define LDAP_TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = LDAP_TAILQ_LAST((head), headname); \ (var); \ - (var) = LDAP_TAILQ_PREV((var), head, type, field)) + (var) = LDAP_TAILQ_PREV((var), headname, field)) #define LDAP_TAILQ_FIRST(head) ((head)->tqh_first) -#define LDAP_TAILQ_LAST(head, type, field) \ - (LDAP_TAILQ_EMPTY(head) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->tqh_last) - offsetof(struct type, field)))) +#define LDAP_TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) #define LDAP_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define LDAP_TAILQ_PREV(elm, head, type, field) \ - ((struct type *)((elm)->field.tqe_prev) == LDAP_TAILQ_FIRST(head) ? \ - NULL : \ - ((struct type *) \ - ((char *)((elm)->field.tqe_prev) - offsetof(struct type, field)))) +#define LDAP_TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define LDAP_TAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ @@ -467,6 +463,9 @@ struct name { \ struct type *cqh_last; /* last element */ \ } +#define LDAP_CIRCLEQ_HEAD_INITIALIZER(head) \ + { (void *)&(head), (void *)&(head) } + #define LDAP_CIRCLEQ_ENTRY(type) \ struct { \ struct type *cqe_next; /* next element */ \ @@ -559,4 +558,36 @@ struct { \ (elm)->field.cqe_next; \ } while (0) +#define LDAP_CIRCLEQ_LOOP_NEXT(head, elm, field) \ + (((elm)->field.cqe_next == (void *)(head)) \ + ? ((head)->cqh_first) \ + : ((elm)->field.cqe_next)) + +#define LDAP_CIRCLEQ_LOOP_PREV(head, elm, field) \ + (((elm)->field.cqe_prev == (void *)(head)) \ + ? ((head)->cqh_last) \ + : ((elm)->field.cqe_prev)) + +#define LDAP_CIRCLEQ_MAKE_HEAD(head, elm, field) do { \ + if ((elm)->field.cqe_prev != (void *)(head)) { \ + (head)->cqh_first->field.cqe_prev = (head)->cqh_last; \ + (head)->cqh_last->field.cqe_next = (head)->cqh_first; \ + (head)->cqh_first = elm; \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + (elm)->field.cqe_prev->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (void *)(head); \ + } \ +} while (0) + +#define LDAP_CIRCLEQ_MAKE_TAIL(head, elm, field) do { \ + if ((elm)->field.cqe_next != (void *)(head)) { \ + (head)->cqh_first->field.cqe_prev = (head)->cqh_last; \ + (head)->cqh_last->field.cqe_next = (head)->cqh_first; \ + (head)->cqh_first = (elm)->field.cqe_next; \ + (head)->cqh_last = elm; \ + (elm)->field.cqe_next->field.cqe_prev = (void *)(head); \ + (elm)->field.cqe_next = (void *)(head); \ + } \ +} while (0) + #endif /* !_LDAP_QUEUE_H_ */