[asterisk-commits] mmichelson: branch 1.4 r103120 - /branches/1.4/apps/app_queue.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Feb 8 12:48:17 CST 2008


Author: mmichelson
Date: Fri Feb  8 12:48:17 2008
New Revision: 103120

URL: http://svn.digium.com/view/asterisk?view=rev&rev=103120
Log:
Prevent a potential three-thread deadlock. Also added a comment block
to explicitly state the locking order necessary inside app_queue.

(closes issue #11862)
Reported by: flujan
Patches:
      11862.patch uploaded by putnopvut (license 60)
	  Tested by: flujan


Modified:
    branches/1.4/apps/app_queue.c

Modified: branches/1.4/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_queue.c?view=diff&rev=103120&r1=103119&r2=103120
==============================================================================
--- branches/1.4/apps/app_queue.c (original)
+++ branches/1.4/apps/app_queue.c Fri Feb  8 12:48:17 2008
@@ -98,6 +98,20 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/astobj2.h"
 #include "asterisk/global_datastores.h"
+
+/* Please read before modifying this file.
+ * There are three locks which are regularly used
+ * throughout this file, the queue list lock, the lock
+ * for each individual queue, and the interface list lock.
+ * Please be extra careful to always lock in the following order
+ * 1) queue list lock
+ * 2) individual queue lock
+ * 3) interface list lock
+ * This order has sort of "evolved" over the lifetime of this
+ * application, but it is now in place this way, so please adhere
+ * to this order!
+ */
+
 
 enum {
 	QUEUE_STRATEGY_RINGALL = 0,
@@ -889,15 +903,16 @@
 {
 	struct member_interface *curint;
 
+	if (interface_exists_global(interface))
+		return 0;
+
 	AST_LIST_LOCK(&interfaces);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
 		if (!strcasecmp(curint->interface, interface)) {
-			if (!interface_exists_global(interface)) {
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
-				AST_LIST_REMOVE_CURRENT(&interfaces, list);
-				free(curint);
-			}
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
+			AST_LIST_REMOVE_CURRENT(&interfaces, list);
+			free(curint);
 			break;
 		}
 	}
@@ -4248,9 +4263,9 @@
 						continue;
 					}
 
-					remove_from_interfaces(cur->interface);
 					q->membercount--;
 					ao2_unlink(q->members, cur);
+					remove_from_interfaces(cur->interface);
 					ao2_ref(cur, -1);
 				}
 




More information about the asterisk-commits mailing list