From 9c47ada7718cbb201ec02dd07dfe1aa10d5fb545 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Wed, 28 Nov 2012 13:22:22 +0100 Subject: [PATCH] Add removal safe TAILQ iterator. TAILQ_FOREACH macro was not safe for element removal as it was accessing the next element in case of a free. This patch is inspired by Linux list handling and provide a new macro TAILQ_FOREACH_SAFE. This macro is removal safe and only differs by a last argument being a temporaty pointer to an element. --- src/queue.h | 7 +++++++ src/unix-manager.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/queue.h b/src/queue.h index 0a10f71555..13455aa429 100644 --- a/src/queue.h +++ b/src/queue.h @@ -346,6 +346,13 @@ struct { \ (var) != TAILQ_END(head); \ (var) = TAILQ_NEXT(var, field)) +/* removal safe iterator using a temprary element has last param */ +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for((var) = TAILQ_FIRST(head), \ + (tvar) = TAILQ_FIRST(head) ? TAILQ_NEXT(TAILQ_FIRST(head), field): NULL ; \ + (var) != TAILQ_END(head); \ + (var = tvar), (tvar) = var ? TAILQ_NEXT(var, field): NULL) + #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for((var) = TAILQ_LAST(head, headname); \ (var) != TAILQ_END(head); \ diff --git a/src/unix-manager.c b/src/unix-manager.c index 5230ba7025..8c42c42c5e 100644 --- a/src/unix-manager.c +++ b/src/unix-manager.c @@ -748,7 +748,8 @@ void *UnixManagerThread(void *td) if ((ret == 0) || (TmThreadsCheckFlag(th_v, THV_KILL))) { UnixClient *item; - TAILQ_FOREACH(item, &(&command)->clients, next) { + UnixClient *titem; + TAILQ_FOREACH_SAFE(item, &(&command)->clients, next, titem) { close(item->fd); SCFree(item); }