mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 12:36:58 +00:00
fix memory leak from not freeing the list of queue members when freeing a queue
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@8447 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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.
|
/*!\brief Reload a single queue via realtime.
|
||||||
\return Return the queue, or NULL if it doesn't exist.
|
\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. */
|
/* Delete. */
|
||||||
AST_LIST_REMOVE(&queues, q, list);
|
AST_LIST_REMOVE(&queues, q, list);
|
||||||
ast_mutex_unlock(&q->lock);
|
ast_mutex_unlock(&q->lock);
|
||||||
free(q);
|
destroy_queue(q);
|
||||||
} else
|
} else
|
||||||
ast_mutex_unlock(&q->lock);
|
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;
|
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)
|
static int play_file(struct ast_channel *chan, char *filename)
|
||||||
{
|
{
|
||||||
int res;
|
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);
|
ast_mutex_unlock(&q->lock);
|
||||||
if (q->dead && !q->count) {
|
if (q->dead && !q->count) {
|
||||||
/* It's dead and nobody is in it, so kill it */
|
/* 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);
|
destroy_queue(q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3371,10 +3367,10 @@ static void reload_queues(void)
|
|||||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) {
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) {
|
||||||
if (q->dead) {
|
if (q->dead) {
|
||||||
AST_LIST_REMOVE_CURRENT(&queues, list);
|
AST_LIST_REMOVE_CURRENT(&queues, list);
|
||||||
if (!q->count) {
|
if (!q->count)
|
||||||
free(q);
|
destroy_queue(q);
|
||||||
} else
|
else
|
||||||
ast_log(LOG_WARNING, "XXX Leaking a little memory :( XXX\n");
|
ast_log(LOG_DEBUG, "XXX Leaking a little memory :( XXX\n");
|
||||||
} else {
|
} else {
|
||||||
for (cur = q->members; cur; cur = cur->next)
|
for (cur = q->members; cur; cur = cur->next)
|
||||||
cur->status = ast_device_state(cur->interface);
|
cur->status = ast_device_state(cur->interface);
|
||||||
|
Reference in New Issue
Block a user