diff --git a/include/libwebsockets/lws-misc.h b/include/libwebsockets/lws-misc.h index 823c240bd..f851d61f0 100644 --- a/include/libwebsockets/lws-misc.h +++ b/include/libwebsockets/lws-misc.h @@ -181,12 +181,31 @@ struct lws_dll { /* abstract */ * lws_container_of() helper to recover the start of the containing struct */ +#define lws_dll_add_head lws_dll_add_front + LWS_VISIBLE LWS_EXTERN void lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead); +LWS_VISIBLE LWS_EXTERN void +lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead); + +static LWS_INLINE struct lws_dll * +lws_dll_get_head(struct lws_dll *phead) { return phead->next; } + +static LWS_INLINE struct lws_dll * +lws_dll_get_tail(struct lws_dll *phead) { return phead->prev; } + +/* + * caution, this doesn't track the tail in the head struct. Use + * lws_dll_remove_track_tail() instead of this if you want tail tracking. Using + * this means you can't use lws_dll_add_tail() amd + */ LWS_VISIBLE LWS_EXTERN void lws_dll_remove(struct lws_dll *d); +LWS_VISIBLE LWS_EXTERN void +lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead); + /* another way to do lws_start_foreach_dll_safe() on a list via a cb */ LWS_VISIBLE LWS_EXTERN int diff --git a/lib/core/libwebsockets.c b/lib/core/libwebsockets.c index 40b64d708..18769b635 100644 --- a/lib/core/libwebsockets.c +++ b/lib/core/libwebsockets.c @@ -80,9 +80,34 @@ lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead) if (d->next) d->next->prev = d; /* our prev ptr is first ptr */ - d->prev = phead; + d->prev = NULL; /* set the first guy to be us */ phead->next = d; + + /* list tail */ + if (!phead->prev) + phead->prev = d; +} + +void +lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead) +{ + if (d->prev) + return; + + /* our previous guy is current last guy */ + d->prev = phead->prev; + /* if there is a prev guy, set his next ptr to our prev ptr */ + if (d->prev) + d->prev->next = d; + /* our next ptr is NULL */ + d->next = NULL; + /* set the last guy to be us */ + phead->prev = d; + + /* list tail */ + if (!phead->prev) + phead->prev = d; } /* situation is: @@ -138,6 +163,21 @@ lws_dll_remove(struct lws_dll *d) d->next = NULL; } +void +lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead) +{ + if (!d->prev) /* ie, not part of the list */ + return; + + /* track the tail if it was us... phead may be NULL tho */ + + if (phead && phead->prev == d) + phead->prev = d->prev; + + lws_dll_remove(d); +} + + int lws_dll_foreach_safe(struct lws_dll *phead, int (*cb)(struct lws_dll *d)) {