diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-09-03 20:18:14 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-09-03 20:18:14 +0000 |
commit | 56b94d307157e7213465d56ea887ed3f3f2b1191 (patch) | |
tree | e109c9c2e84fe096f196ff2f80c946cc257df427 /apps/app_queue.c | |
parent | 771fe9e49b26fb30058dba710c849d901ff9af7d (diff) |
Merged revisions 140975 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
........
r140975 | mmichelson | 2008-09-03 15:16:12 -0500 (Wed, 03 Sep 2008) | 4 lines
Fix some locking order issues in app_queue. This was
brought up by atis on IRC a while ago.
........
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@140976 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r-- | apps/app_queue.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 082e40f0d..ba003911d 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1015,7 +1015,7 @@ static int add_to_interfaces(const char *interface) return 0; } -static int interface_exists_global(const char *interface) +static int interface_exists_global(const char *interface, int lock_queue_container) { struct call_queue *q; struct member *mem, tmpmem; @@ -1023,7 +1023,7 @@ static int interface_exists_global(const char *interface) int ret = 0; ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface)); - queue_iter = ao2_iterator_init(queues, 0); + queue_iter = ao2_iterator_init(queues, lock_queue_container ? 0 : F_AO2I_DONTLOCK); while ((q = ao2_iterator_next(&queue_iter))) { ao2_lock(q); mem_iter = ao2_iterator_init(q->members, 0); @@ -1041,11 +1041,11 @@ static int interface_exists_global(const char *interface) return ret; } -static int remove_from_interfaces(const char *interface) +static int remove_from_interfaces(const char *interface, int lock_queue_container) { struct member_interface *curint; - if (interface_exists_global(interface)) + if (interface_exists_global(interface, lock_queue_container)) return 0; AST_LIST_LOCK(&interfaces); @@ -1371,7 +1371,7 @@ static void rt_handle_member_record(struct call_queue *q, char *interface, const if (paused_str) m->paused = paused; if (strcasecmp(state_interface, m->state_interface)) { - remove_from_interfaces(m->state_interface); + remove_from_interfaces(m->state_interface, 0); ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface)); add_to_interfaces(m->state_interface); } @@ -1390,7 +1390,7 @@ static void free_members(struct call_queue *q, int all) while ((cur = ao2_iterator_next(&mem_iter))) { if (all || !cur->dynamic) { ao2_unlink(q->members, cur); - remove_from_interfaces(cur->state_interface); + remove_from_interfaces(cur->state_interface, 1); q->membercount--; } ao2_ref(cur, -1); @@ -1556,7 +1556,7 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as while ((m = ao2_iterator_next(&mem_iter))) { if (m->dead) { ao2_unlink(q->members, m); - remove_from_interfaces(m->state_interface); + remove_from_interfaces(m->state_interface, 0); q->membercount--; } ao2_ref(m, -1); @@ -1644,6 +1644,7 @@ static void update_realtime_members(struct call_queue *q) return; } + ao2_lock(queues); ao2_lock(q); /* Temporarily set realtime members dead so we can detect deleted ones.*/ @@ -1667,12 +1668,13 @@ static void update_realtime_members(struct call_queue *q) while ((m = ao2_iterator_next(&mem_iter))) { if (m->dead) { ao2_unlink(q->members, m); - remove_from_interfaces(m->state_interface); + remove_from_interfaces(m->state_interface, 0); q->membercount--; } ao2_ref(m, -1); } ao2_unlock(q); + ao2_unlock(queues); ast_config_destroy(member_config); } @@ -3904,6 +3906,7 @@ static int remove_from_queue(const char *queuename, const char *interface) ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface)); if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) { + ao2_lock(queues); ao2_lock(q); if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) { /* XXX future changes should beware of this assumption!! */ @@ -3919,7 +3922,7 @@ static int remove_from_queue(const char *queuename, const char *interface) "MemberName: %s\r\n", q->name, mem->interface, mem->membername); ao2_unlink(q->members, mem); - remove_from_interfaces(mem->state_interface); + remove_from_interfaces(mem->state_interface, 0); ao2_ref(mem, -1); if (queue_persistent_members) @@ -3930,6 +3933,7 @@ static int remove_from_queue(const char *queuename, const char *interface) res = RES_EXISTS; } ao2_unlock(q); + ao2_unlock(queues); queue_unref(q); } @@ -5344,7 +5348,7 @@ static int reload_queues(int reload) cur = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK); /* Only attempt removing from interfaces list if the new state_interface is different than the old one */ if (cur && strcasecmp(cur->state_interface, state_interface)) { - remove_from_interfaces(cur->state_interface); + remove_from_interfaces(cur->state_interface, 0); } newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface); if (!cur || (cur && strcasecmp(cur->state_interface, state_interface))) @@ -5372,7 +5376,7 @@ static int reload_queues(int reload) } q->membercount--; ao2_unlink(q->members, cur); - remove_from_interfaces(cur->interface); + remove_from_interfaces(cur->interface, 0); ao2_ref(cur, -1); } |