[asterisk-commits] mmichelson: branch 1.6.1 r140977 - in /branches/1.6.1: ./ apps/app_queue.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Sep 3 15:18:59 CDT 2008


Author: mmichelson
Date: Wed Sep  3 15:18:58 2008
New Revision: 140977

URL: http://svn.digium.com/view/asterisk?view=rev&rev=140977
Log:
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.


........

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/apps/app_queue.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/branches/1.6.1/apps/app_queue.c?view=diff&rev=140977&r1=140976&r2=140977
==============================================================================
--- branches/1.6.1/apps/app_queue.c (original)
+++ branches/1.6.1/apps/app_queue.c Wed Sep  3 15:18:58 2008
@@ -984,7 +984,7 @@
 	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;
@@ -992,7 +992,7 @@
 	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);
@@ -1010,11 +1010,11 @@
 	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);
@@ -1354,7 +1354,7 @@
  			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);
  			}	   
@@ -1392,7 +1392,7 @@
 	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);
@@ -1560,7 +1560,7 @@
 		if (m->dead) {
 			ast_queue_log(q->name, "REALTIME", m->interface, "REMOVEMEMBER", "%s", "");
 			ao2_unlink(q->members, m);
-			remove_from_interfaces(m->state_interface);
+			remove_from_interfaces(m->state_interface, 0);
 			q->membercount--;
 		}
 		ao2_ref(m, -1);
@@ -1643,6 +1643,7 @@
 		return;
 	}
 
+	ao2_lock(queues);
 	ao2_lock(q);
 	
 	/* Temporarily set realtime  members dead so we can detect deleted ones.*/ 
@@ -1668,12 +1669,13 @@
 		if (m->dead) {
 			ast_queue_log(q->name, "REALTIME", m->interface, "REMOVEMEMBER", "%s", "");
 			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);
 }
 
@@ -3975,6 +3977,7 @@
 
 	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!! */
@@ -3990,7 +3993,7 @@
 				"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)
@@ -4001,6 +4004,7 @@
 			res = RES_EXISTS;
 		}
 		ao2_unlock(q);
+		ao2_unlock(queues);
 		queue_unref(q);
 	}
 
@@ -5436,7 +5440,7 @@
 						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)))
@@ -5464,7 +5468,7 @@
 					}
 					q->membercount--;
 					ao2_unlink(q->members, cur);
-					remove_from_interfaces(cur->interface);
+					remove_from_interfaces(cur->interface, 0);
 					ao2_ref(cur, -1);
 				}
 




More information about the asterisk-commits mailing list