Archived
14
0
Fork 0

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
This commit is contained in:
russell 2006-01-22 19:09:50 +00:00
parent c85d5472e9
commit ec44e79c9c

View file

@ -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);