[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