summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2008-11-14 16:53:38 +0000
committerMark Michelson <mmichelson@digium.com>2008-11-14 16:53:38 +0000
commitcf6c66de65b344aab18f032feb4aa851fde3f3ad (patch)
tree9c95c9f6a5849fa85869f98ea8021b673b948d7f /apps
parentcb90752b0d2de3d1c9711bf4eb7095f3215f3721 (diff)
Fix some refcounting in app_queue.c and change the
hashing used by app_queue.c to be case-insensitive. This is accomplished by adding a new case-insensitive hashing function. This was necessary to prevent bad refcount errors (and potential crashes) which would occur due to the fact that queues were initially read from the config file in a case-sensitive manner. Then, when a user issued a CLI command or manager action, we allowed for case-insensitive input and used that input to directly try to find the queue in the hash table. The result was either that we could not find a queue that was input or worse, we would end up hashing to a completely bogus value based on the input. This commit resolves the problem presented in issue #13703. However, that issue was reported against 1.6.0. Since this fix introduces a behavior change, I am electing to not place this same fix in to the 1.6.0 or 1.6.1 branches, and instead will opt for a change which does not change behavior. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@156883 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rw-r--r--apps/app_queue.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index b3081028d..07829042b 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -67,6 +67,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>
+#include <ctype.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
@@ -850,7 +851,8 @@ static int strat2int(const char *strategy)
static int queue_hash_cb(const void *obj, const int flags)
{
const struct call_queue *q = obj;
- return ast_str_hash(q->name);
+
+ return ast_str_case_hash(q->name);
}
static int queue_cmp_cb(void *obj, void *arg, void *data, int flags)
@@ -1671,7 +1673,6 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
/* Delete if unused (else will be deleted when last caller leaves). */
ao2_unlink(queues, q);
ao2_unlock(q);
- queue_unref(q);
}
return NULL;
}
@@ -2192,8 +2193,6 @@ static void leave_queue(struct queue_ent *qe)
if (q->dead) {
/* It's dead and nobody is in it, so kill it */
ao2_unlink(queues, q);
- /* unref the container's reference to the queue */
- queue_unref(q);
}
/* unref the explicit ref earlier in the function */
queue_unref(q);
@@ -2248,11 +2247,10 @@ static int compare_weight(struct call_queue *rq, struct member *member)
}
}
ao2_unlock(q);
+ queue_unref(q);
if (found) {
- queue_unref(q);
break;
}
- queue_unref(q);
}
return found;
}
@@ -4186,6 +4184,8 @@ static int remove_from_queue(const char *queuename, const char *interface)
if (!mem->dynamic) {
ao2_ref(mem, -1);
ao2_unlock(q);
+ queue_unref(q);
+ ao2_unlock(queues);
return RES_NOT_DYNAMIC;
}
q->membercount--;
@@ -5691,13 +5691,15 @@ static char *__queues_show(struct mansession *s, int fd, int argc, char **argv)
}
}
- queue_iter = ao2_iterator_init(queues, 0);
+ queue_iter = ao2_iterator_init(queues, F_AO2I_DONTLOCK);
+ ao2_lock(queues);
while ((q = ao2_iterator_next(&queue_iter))) {
float sl;
ao2_lock(q);
if (argc == 3 && strcasecmp(q->name, argv[2])) {
ao2_unlock(q);
+ queue_unref(q);
continue;
}
found = 1;
@@ -5768,6 +5770,7 @@ static char *__queues_show(struct mansession *s, int fd, int argc, char **argv)
}
queue_unref(q); /* Unref the iterator's reference */
}
+ ao2_unlock(queues);
if (!found) {
if (argc == 3)
ast_str_set(&out, 0, "No such queue: %s.", argv[2]);