From ced952a4c6244134f1578f1ef69be3ed7f09c81d Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 12 Jan 2022 09:33:36 +1100 Subject: [PATCH] [client] ll: add new functionallity to allow removal of items --- client/include/ll.h | 80 +++++++++++++++++++++++++++++++++++++++++++-- client/src/ll.c | 39 +++------------------- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/client/include/ll.h b/client/include/ll.h index a8a24dfe..a9b1e69a 100644 --- a/client/include/ll.h +++ b/client/include/ll.h @@ -18,8 +18,27 @@ * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _H_LL_ +#define _H_LL_ + #include -struct ll; + +#include "common/locking.h" + +struct ll_item +{ + void * data; + struct ll_item * prev, * next; +}; + +struct ll +{ + struct ll_item * head; + struct ll_item * tail; + struct ll_item * pos; + unsigned int count; + LG_Lock lock; +}; struct ll * ll_new(); void ll_free (struct ll * list); @@ -27,7 +46,62 @@ void ll_push (struct ll * list, void * data); bool ll_shift (struct ll * list, void ** data); bool ll_peek_head(struct ll * list, void ** data); bool ll_peek_tail(struct ll * list, void ** data); -unsigned int ll_count (struct ll * list); -void ll_reset (struct ll * list); bool ll_walk (struct ll * list, void ** data); + +#define ll_lock(ll) LG_LOCK((ll)->lock) +#define ll_unlock(ll) LG_UNLOCK((ll)->lock) + +#define ll_forEachNL(ll, item, v) \ + for(struct ll_item * item = (ll)->head, * _ = (ll)->head->next; (item);) \ + for((v) = (__typeof__(v))((item)->data); (item); (item) = _, \ + _ = _ ? _->next : NULL, (v) = (__typeof__(v))((item)->data)) + +static inline unsigned int ll_count(struct ll * list) +{ + return list->count; +} + +static inline void ll_reset (struct ll * list) +{ + LG_LOCK(list->lock); + list->pos = NULL; + LG_UNLOCK(list->lock); +} + +static inline void ll_removeNL(struct ll * list, struct ll_item * item) +{ + --list->count; + + if (list->head == item) + list->head = item->next; + + if (list->tail == item) + list->tail = item->prev; + + if (item->prev) + item->prev->next = item->next; + + if (item->next) + item->next->prev = item->prev; + + list->pos = NULL; +} + +static inline bool ll_removeData(struct ll * list, void * match) +{ + void * data; + ll_lock(list); + ll_forEachNL(list, item, data) + if (data == match) + { + ll_removeNL(list, item); + ll_unlock(list); + return true; + } + ll_unlock(list); + + return false; +} + +#endif diff --git a/client/src/ll.c b/client/src/ll.c index a5587465..9642694a 100644 --- a/client/src/ll.c +++ b/client/src/ll.c @@ -24,21 +24,6 @@ #include "common/locking.h" #include -struct ll_item -{ - void * data; - struct ll_item * next; -}; - -struct ll -{ - struct ll_item * head; - struct ll_item * tail; - struct ll_item * pos; - unsigned int count; - LG_Lock lock; -}; - struct ll * ll_new(void) { struct ll * list = malloc(sizeof(*list)); @@ -70,14 +55,18 @@ void ll_push(struct ll * list, void * data) if (!list->head) { + item->prev = NULL; list->head = item; list->tail = item; LG_UNLOCK(list->lock); return; } + item->prev = list->tail; + list->tail->next = item; list->tail = item; + LG_UNLOCK(list->lock); } @@ -90,13 +79,8 @@ bool ll_shift(struct ll * list, void ** data) return false; } - --list->count; struct ll_item * item = list->head; - list->head = item->next; - list->pos = NULL; - if (list->tail == item) - list->tail = NULL; - + ll_removeNL(list, item); LG_UNLOCK(list->lock); if (data) @@ -136,19 +120,6 @@ bool ll_peek_tail(struct ll * list, void ** data) return true; } -unsigned int ll_count(struct ll * list) -{ - return list->count; -} - -void ll_reset (struct ll * list) -{ - LG_LOCK(list->lock); - list->pos = NULL; - LG_UNLOCK(list->lock); -} - - bool ll_walk(struct ll * list, void ** data) { LG_LOCK(list->lock);