[Asterisk-cvs] asterisk/apps app_queue.c,1.126,1.127

markster at lists.digium.com markster at lists.digium.com
Sat Mar 19 11:41:00 CST 2005


Update of /usr/cvsroot/asterisk/apps
In directory mongoose.digium.com:/tmp/cvs-serv13209/apps

Modified Files:
	app_queue.c 
Log Message:
Fix queue stuff (bug #3797)


Index: app_queue.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- app_queue.c	4 Mar 2005 00:59:58 -0000	1.126
+++ app_queue.c	19 Mar 2005 17:35:59 -0000	1.127
@@ -746,35 +746,33 @@
 	return update_status(q, member, status);
 }
 
-static int compare_weight(struct ast_call_queue *req_q, struct localuser *req_user, char *qname) 
+static int compare_weight(struct ast_call_queue *rq, struct member *member)
 {
 /* traverse all defined queues which have calls waiting and contain this member
    return 0 if no other queue has precedence (higher weight) or 1 if found  */
 	struct ast_call_queue *q;
 	struct member *mem;
-	int found = 0, weight = 0, calls = 0;
-	char name[80] = "";
-	
-	strncpy(name, req_q->name, sizeof(name) - 1);
-	weight = req_q->weight;
-	calls = req_q->count;
+	int found = 0;
 	
+	/* avoid deadlock which can occur under specific condition.
+	 * another queue-walking func may be waiting for rq->lock, which
+	 * was set by try_calling, but won't unlock til this finishes,
+	 * yet we're waiting for &qlock.  happy fun times! */
+	ast_mutex_unlock(&rq->lock);
 	ast_mutex_lock(&qlock);
-	for (q = queues; q; q = q->next) { /* spin queues */
-		ast_mutex_lock(&q->lock);
-		if (!strcasecmp(q->name, name)) { /* don't check myself */
-			ast_mutex_unlock(&q->lock);
+	ast_mutex_lock(&rq->lock);
+	for (q = queues; q; q = q->next) {
+		if (q == rq) /* don't check myself */
 			continue; 
-		}
-		if (q->count && q->members) { /* check only if calls waiting and has members */
-			for (mem = q->members; mem; mem = mem->next) {  /* spin members */
-				if (!strcasecmp(mem->interface, req_user->interface)) {
+		ast_mutex_lock(&q->lock);
+		if (q->count && q->members) {
+			for (mem = q->members; mem; mem = mem->next) {
+				if (mem == member) {
 					ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
-					if (q->weight > weight) {
-						ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, name, weight, calls);
+					if (q->weight > rq->weight) {
+						ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
 						found = 1;
-						strncpy(qname, q->name, sizeof(qname) - 1);
-						break;  /* stop looking for more members */
+						break;
 					}
 				}
 			}
@@ -795,18 +793,7 @@
 	int status;
 	char tech[256];
 	char *location;
-	char qname[80] = "";
 
-	if (use_weight) { /* fast path */
-		if (compare_weight(qe->parent,tmp,qname)) {
-			ast_verbose(VERBOSE_PREFIX_3 "Attempt (%s: %s) delayed by higher priority queue (%s).\n", qe->parent->name, tmp->interface, qname);
-			if (qe->chan->cdr)
-				ast_cdr_busy(qe->chan->cdr);
-			tmp->stillgoing = 0;
-			(*busies)++;
-			return 0;
-		}
-	}
 	if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
@@ -825,6 +812,14 @@
 		tmp->stillgoing = 0;
 		return 0;
 	}
+	if (use_weight && compare_weight(qe->parent,tmp->member)) {
+		ast_log(LOG_DEBUG, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
+		if (qe->chan->cdr)
+			ast_cdr_busy(qe->chan->cdr);
+		tmp->stillgoing = 0;
+		(*busies)++;
+		return 0;
+	}
 
 	strncpy(tech, tmp->interface, sizeof(tech) - 1);
 	if ((location = strchr(tech, '/')))




More information about the svn-commits mailing list