aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-01-22 19:03:53 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-01-22 19:03:53 +0000
commit407886f2525a7e436421dc630d30306b8541f561 (patch)
tree1b0be431314a72e4ea85553d309e05497366df91
parent1209717ab0587ee40a71ab55ccc393bda42806d7 (diff)
fix memory leak from not freeing the queue member list when freeing an old queue
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@8445 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--apps/app_queue.c89
1 files changed, 45 insertions, 44 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 11e750cc2..56b8abf9f 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -755,6 +755,48 @@ 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);
+}
+
+static void remove_queue(struct ast_call_queue *q)
+{
+ struct ast_call_queue *cur, *prev = NULL;
+
+ ast_mutex_lock(&qlock);
+ for (cur = queues; cur; cur = cur->next) {
+ if (cur == q) {
+ if (prev)
+ prev->next = cur->next;
+ else
+ queues = cur->next;
+ } else {
+ prev = cur;
+ }
+ }
+ ast_mutex_unlock(&qlock);
+}
/*!\brief Reload a single queue via realtime.
\return Return the queue, or NULL if it doesn't exist.
@@ -811,7 +853,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
prev_q->next = q->next;
}
ast_mutex_unlock(&q->lock);
- free(q);
+ destroy_queue(q);
} else
ast_mutex_unlock(&q->lock);
}
@@ -997,48 +1039,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)
-{
- struct ast_call_queue *cur, *prev = NULL;
-
- ast_mutex_lock(&qlock);
- for (cur = queues; cur; cur = cur->next) {
- if (cur == q) {
- if (prev)
- prev->next = cur->next;
- else
- queues = cur->next;
- } else {
- prev = cur;
- }
- }
- ast_mutex_unlock(&qlock);
- free_members(q, 1);
- ast_mutex_destroy(&q->lock);
- free(q);
-}
-
static int play_file(struct ast_channel *chan, char *filename)
{
int res;
@@ -1246,6 +1246,7 @@ 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 */
+ remove_queue(q);
destroy_queue(q);
}
}
@@ -3266,7 +3267,7 @@ static void reload_queues(void)
else
queues = q->next;
if (!q->count) {
- free(q);
+ destroy_queue(q);
} else
ast_log(LOG_WARNING, "XXX Leaking a little memory :( XXX\n");
} else {