From ec44e79c9c2265c3dc306514c296f150ef785749 Mon Sep 17 00:00:00 2001 From: russell Date: Sun, 22 Jan 2006 19:09:50 +0000 Subject: fix memory leak from not freeing the list of queue members when freeing a queue git-svn-id: http://svn.digium.com/svn/asterisk/trunk@8447 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 68 ++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'apps') diff --git a/apps/app_queue.c b/apps/app_queue.c index 765b653f2..b380dd4e5 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -787,6 +787,30 @@ static void rt_handle_member_record(struct ast_call_queue *q, char *interface, c } } +static void free_members(struct ast_call_queue *q, int all) +{ + /* Free non-dynamic members */ + struct member *curm, *next, *prev = NULL; + + for (curm = q->members; curm; curm = next) { + next = curm->next; + if (all || !curm->dynamic) { + if (prev) + prev->next = next; + else + q->members = next; + free(curm); + } else + prev = curm; + } +} + +static void destroy_queue(struct ast_call_queue *q) +{ + free_members(q, 1); + ast_mutex_destroy(&q->lock); + free(q); +} /*!\brief Reload a single queue via realtime. \return Return the queue, or NULL if it doesn't exist. @@ -838,7 +862,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc /* Delete. */ AST_LIST_REMOVE(&queues, q, list); ast_mutex_unlock(&q->lock); - free(q); + destroy_queue(q); } else ast_mutex_unlock(&q->lock); } @@ -1022,37 +1046,6 @@ ast_log(LOG_NOTICE, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, q return res; } -static void free_members(struct ast_call_queue *q, int all) -{ - /* Free non-dynamic members */ - struct member *curm, *next, *prev; - - curm = q->members; - prev = NULL; - while(curm) { - next = curm->next; - if (all || !curm->dynamic) { - if (prev) - prev->next = next; - else - q->members = next; - free(curm); - } else - prev = curm; - curm = next; - } -} - -static void destroy_queue(struct ast_call_queue *q) -{ - AST_LIST_LOCK(&queues); - AST_LIST_REMOVE(&queues, q, list); - AST_LIST_UNLOCK(&queues); - free_members(q, 1); - ast_mutex_destroy(&q->lock); - free(q); -} - static int play_file(struct ast_channel *chan, char *filename) { int res; @@ -1260,6 +1253,9 @@ ast_log(LOG_NOTICE, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name ast_mutex_unlock(&q->lock); if (q->dead && !q->count) { /* It's dead and nobody is in it, so kill it */ + AST_LIST_LOCK(&queues); + AST_LIST_REMOVE(&queues, q, list); + AST_LIST_UNLOCK(&queues); destroy_queue(q); } } @@ -3371,10 +3367,10 @@ static void reload_queues(void) AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) { if (q->dead) { AST_LIST_REMOVE_CURRENT(&queues, list); - if (!q->count) { - free(q); - } else - ast_log(LOG_WARNING, "XXX Leaking a little memory :( XXX\n"); + if (!q->count) + destroy_queue(q); + else + ast_log(LOG_DEBUG, "XXX Leaking a little memory :( XXX\n"); } else { for (cur = q->members; cur; cur = cur->next) cur->status = ast_device_state(cur->interface); -- cgit v1.2.3