diff options
author | Richard Mudgett <rmudgett@digium.com> | 2011-08-22 20:01:30 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2011-08-22 20:01:30 +0000 |
commit | b92dcb0c82d37e42ef6b16fc64a32e098ee6cdd6 (patch) | |
tree | 5822cc9edd4d41c0598d4f168aa852c1a0096db0 /apps | |
parent | eb46a4128ac43bd43bf52fd7ba0859ce49eb09cf (diff) |
Merged revisions 332875,332878 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10
................
r332875 | rmudgett | 2011-08-22 14:41:03 -0500 (Mon, 22 Aug 2011) | 1 line
Fix merge property.
................
r332878 | rmudgett | 2011-08-22 14:46:25 -0500 (Mon, 22 Aug 2011) | 25 lines
Merged revisions 332874 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r332874 | rmudgett | 2011-08-22 14:32:19 -0500 (Mon, 22 Aug 2011) | 18 lines
Reference leaks in app_queue.
* Fixed load_realtime_queue() leaking a queue reference when it overwrites
q when processing a realtime queue.
(issue ASTERISK-18265)
* Make join_queue() unreference the queue returned by
load_realtime_queue() when it is done with the pointer. The
load_realtime_queue() returns a reference to the just loaded realtime
queue.
* Fixed queues container reference leak in queues_data_provider_get().
* queue_unref() should not return q that was just unreferenced.
* Made logic in __queues_show() and queues_data_provider_get() when
calling load_realtime_queue() easier to understand.
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@332881 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_queue.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 683b5faa5..0e57ec4e1 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1310,7 +1310,7 @@ static inline struct call_queue *queue_ref(struct call_queue *q) static inline struct call_queue *queue_unref(struct call_queue *q) { ao2_ref(q, -1); - return q; + return NULL; } #endif @@ -2376,6 +2376,7 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as return q; } +/*! \note Returns a reference to the loaded realtime queue. */ static struct call_queue *load_realtime_queue(const char *queuename) { struct ast_variable *queue_vars; @@ -2409,17 +2410,15 @@ static struct call_queue *load_realtime_queue(const char *queuename) } if (q) { prev_weight = q->weight ? 1 : 0; + queue_t_unref(q, "Need to find realtime queue"); } ao2_lock(queues); q = find_queue_by_name_rt(queuename, queue_vars, member_config); - if (member_config) { - ast_config_destroy(member_config); - } - if (queue_vars) { - ast_variables_destroy(queue_vars); - } + ast_config_destroy(member_config); + ast_variables_destroy(queue_vars); + /* update the use_weight value if the queue's has gained or lost a weight */ if (q) { if (!q->weight && prev_weight) { @@ -2522,6 +2521,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * *reason = QUEUE_JOINEMPTY; ao2_unlock(q); ao2_unlock(queues); + queue_t_unref(q, "Done with realtime queue"); return res; } } @@ -2585,6 +2585,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * } ao2_unlock(q); ao2_unlock(queues); + queue_t_unref(q, "Done with realtime queue"); return res; } @@ -7151,13 +7152,16 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char * * queues which have been deleted from realtime but which have not yet * been deleted from the in-core container */ - if (q->realtime && !(realtime_queue = load_realtime_queue(q->name))) { - ao2_unlock(q); - queue_t_unref(q, "Done with iterator"); - continue; - } else if (q->realtime) { + if (q->realtime) { + realtime_queue = load_realtime_queue(q->name); + if (!realtime_queue) { + ao2_unlock(q); + queue_t_unref(q, "Done with iterator"); + continue; + } queue_t_unref(realtime_queue, "Queue is already in memory"); } + if (argc == 3 && strcasecmp(q->name, argv[2])) { ao2_unlock(q); queue_t_unref(q, "Done with iterator"); @@ -8481,11 +8485,13 @@ static int queues_data_provider_get(const struct ast_data_search *search, i = ao2_iterator_init(queues, 0); while ((queue = ao2_iterator_next(&i))) { ao2_lock(queue); - if (queue->realtime && !(queue_realtime = load_realtime_queue(queue->name))) { - ao2_unlock(queue); - queue_unref(queue); - continue; - } else if (queue->realtime) { + if (queue->realtime) { + queue_realtime = load_realtime_queue(queue->name); + if (!queue_realtime) { + ao2_unlock(queue); + queue_unref(queue); + continue; + } queue_unref(queue_realtime); } @@ -8493,6 +8499,7 @@ static int queues_data_provider_get(const struct ast_data_search *search, ao2_unlock(queue); queue_unref(queue); } + ao2_iterator_destroy(&i); return 0; } |