[Asterisk-cvs] asterisk/apps app_queue.c,1.101,1.102

markster at lists.digium.com markster at lists.digium.com
Sun Dec 19 16:48:21 CST 2004


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

Modified Files:
	app_queue.c 
Log Message:
Add some more of kpflemings optimizations (bugs #3092, #3094)


Index: app_queue.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -d -r1.101 -r1.102
--- app_queue.c	19 Dec 2004 21:30:55 -0000	1.101
+++ app_queue.c	19 Dec 2004 21:44:24 -0000	1.102
@@ -154,6 +154,21 @@
 /* queues.conf [general] option */
 static int queue_persistent_members = 0;
 
+#define QUEUE_FLAG_RINGBACKONLY		(1 << 0)
+#define QUEUE_FLAG_MUSICONHOLD		(1 << 1)
+#define QUEUE_FLAG_DATAQUALITY		(1 << 2)
+#define QUEUE_FLAG_REDIR_IN		(1 << 3)
+#define QUEUE_FLAG_REDIR_OUT		(1 << 4)
+#define QUEUE_FLAG_DISCON_IN		(1 << 5)
+#define QUEUE_FLAG_DISCON_OUT		(1 << 6)
+#define QUEUE_FLAG_MONJOIN		(1 << 7)	/* Should we join the two files when we are done with the call */
+#define QUEUE_FLAG_DEAD			(1 << 8)	/* Whether the queue is dead or not */
+#define QUEUE_FLAG_JOINEMPTY		(1 << 9)	/* Do we care if the queue has no members? */
+#define QUEUE_FLAG_EVENTWHENCALLED	(1 << 10)	/* Generate an event when the agent is called (before pickup) */
+#define QUEUE_FLAG_LEAVEWHENEMPTY	(1 << 11)	/* If all agents leave the queue, remove callers from the queue */
+#define QUEUE_FLAG_REPORTHOLDTIME	(1 << 12)	/* Should we report caller hold time to answering member? */
+#define QUEUE_FLAG_WRAPPED		(1 << 13)	/* Round Robin - wrapped around? */
+
 /* We define a customer "local user" structure because we
    use it not only for keeping track of what is in use but
    also for keeping track of who we're dialing. */
@@ -164,13 +179,7 @@
 	int stillgoing;
 	int metric;
 	int oldstatus;
-	int allowredirect_in;
-	int allowredirect_out;
-	int ringbackonly;
-	int musiconhold;
-	int dataquality;
-	int allowdisconnect_in;
-	int allowdisconnect_out;
+	int flags;			/* flag bits */
 	time_t lastcall;
 	struct member *member;
 	struct localuser *next;
@@ -211,6 +220,7 @@
 	char moh[80];			/* Name of musiconhold to be used */
 	char announce[80];		/* Announcement to play when call is answered */
 	char context[80];		/* Context for this queue */
+	int flags;			/* flag bits */
 	int strategy;			/* Queueing strategy */
 	int announcefrequency;          /* How often to announce their position */
 	int roundingseconds;            /* How many seconds do we round to? */
@@ -221,7 +231,6 @@
 	int servicelevel;               /* seconds setting for servicelevel*/
 	int callscompletedinsl;         /* Number of queue calls answererd with servicelevel*/
 	char monfmt[8];                 /* Format to use when recording calls */
-	int monjoin;                    /* Should we join the two files when we are done with the call */
 	char sound_next[80];            /* Sound file: "Your call is now first in line" (def. queue-youarenext) */
 	char sound_thereare[80];        /* Sound file: "There are currently" (def. queue-thereare) */
 	char sound_calls[80];           /* Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
@@ -236,18 +245,12 @@
 	int maxlen;			/* Max number of entries in queue */
 	int wrapuptime;		/* Wrapup Time */
 
-	int dead;			/* Whether this queue is dead or not */
 	int retry;			/* Retry calling everyone after this amount of time */
 	int timeout;			/* How long to wait for an answer */
 	
 	/* Queue strategy things */
 	
 	int rrpos;			/* Round Robin - position */
-	int wrapped;			/* Round Robin - wrapped around? */
-	int joinempty;			/* Do we care if the queue has no members? */
-	int eventwhencalled;			/* Generate an event when the agent is called (before pickup) */
-	int leavewhenempty;		/* If all agents leave the queue, remove callers from the queue */
-	int reportholdtime;		/* Should we report caller hold time to member? */
 	int memberdelay;		/* Seconds to delay connecting member to caller */
 
 	struct member *members;		/* Member channels to be tried */
@@ -405,7 +408,7 @@
 		if (!strcasecmp(q->name, queuename)) {
 			/* This is our one */
 			ast_mutex_lock(&q->lock);
-			if ((!has_no_members(q) || q->joinempty) && (!q->maxlen || (q->count < q->maxlen))) {
+			if ((!has_no_members(q) || ast_test_flag(q, QUEUE_FLAG_JOINEMPTY)) && (!q->maxlen || (q->count < q->maxlen))) {
 				/* There's space for us, put us at the right position inside
 				 * the queue. 
 				 * Take into account the priority of the calling user */
@@ -643,7 +646,7 @@
 		cur = cur->next;
 	}
 	ast_mutex_unlock(&q->lock);
-	if (q->dead && !q->count) {	
+	if (ast_test_flag(q, QUEUE_FLAG_DEAD) && !q->count) {	
 		/* It's dead and nobody is in it, so kill it */
 		destroy_queue(q);
 	}
@@ -773,7 +776,7 @@
 		tmp->stillgoing = 0;
 		return 0;
 	} else {
-		if (qe->parent->eventwhencalled) {
+		if (ast_test_flag(qe->parent, QUEUE_FLAG_EVENTWHENCALLED)) {
 			manager_event(EVENT_FLAG_AGENT, "AgentCalled",
 						"AgentCalled: %s\r\n"
 						"ChannelCalling: %s\r\n"
@@ -859,7 +862,7 @@
 		qe->parent->rrpos = best->metric % 1000;
 	} else {
 		/* Just increment rrpos */
-		if (!qe->parent->wrapped) {
+		if (!ast_test_flag(qe->parent, QUEUE_FLAG_WRAPPED)) {
 			/* No more channels, start over */
 			qe->parent->rrpos = 0;
 		} else {
@@ -867,7 +870,7 @@
 			qe->parent->rrpos++;
 		}
 	}
-	qe->parent->wrapped = 0;
+	ast_clear_flag(qe->parent, QUEUE_FLAG_WRAPPED);
 	return 0;
 }
 
@@ -889,7 +892,7 @@
 
 #define AST_MAX_WATCHERS 256
 
-static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit)
+static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, struct localuser *flags, char *digit)
 {
 	char *queue = qe->parent->name;
 	struct localuser *o;
@@ -939,10 +942,7 @@
 					if (option_verbose > 2)
 						ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
 					peer = o;
-					*allowredir_in = o->allowredirect_in;
-					*allowredir_out = o->allowredirect_out;
-					*allowdisconnect_in = o->allowdisconnect_in;
-					*allowdisconnect_out = o->allowdisconnect_out;
+					ast_copy_flags(flags, o, QUEUE_FLAG_REDIR_IN & QUEUE_FLAG_REDIR_OUT & QUEUE_FLAG_DISCON_IN & QUEUE_FLAG_DISCON_OUT);
 				}
 			} else if (o->chan && (o->chan == winner)) {
 				if (!ast_strlen_zero(o->chan->call_forward)) {
@@ -1028,10 +1028,7 @@
 								if (option_verbose > 2)
 									ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
 								peer = o;
-								*allowredir_in = o->allowredirect_in;
-								*allowredir_out = o->allowredirect_out;
-								*allowdisconnect_in = o->allowdisconnect_out;
-								*allowdisconnect_out = o->allowdisconnect_out;
+								ast_copy_flags(flags, o, QUEUE_FLAG_REDIR_IN & QUEUE_FLAG_REDIR_OUT & QUEUE_FLAG_DISCON_IN & QUEUE_FLAG_DISCON_OUT);
 							}
 							break;
 						case AST_CONTROL_BUSY:
@@ -1099,7 +1096,7 @@
 				*to=-1;
 				return NULL;
 			}
-			if (f && (f->frametype == AST_FRAME_DTMF) && allowdisconnect_out && (f->subclass == '*')) {
+			if (f && (f->frametype == AST_FRAME_DTMF) && ast_test_flag(flags, QUEUE_FLAG_DISCON_OUT) && (f->subclass == '*')) {
 			    if (option_verbose > 3)
 					ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 				*to=0;
@@ -1148,22 +1145,15 @@
 
 	/* This is the holding pen for callers 2 through maxlen */
 	for (;;) {
-		/* Atomically read the parent head -- does not need a lock */
-		ch = qe->parent->head;
-
-		/* If we are now at the top of the head, break out */
-		if (ch == qe) {
-			if (option_debug)
-				ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
+		if (is_our_turn(qe))
 			break;
-		}
 
 		/* If we have timed out, break out */
 		if (qe->expire && (time(NULL) > qe->expire))
 			break;
 
 		/* leave the queue if no agents, if enabled */
-		if (has_no_members(qe->parent) && qe->parent->leavewhenempty) {
+		if (ast_test_flag(qe->parent, QUEUE_FLAG_LEAVEWHENEMPTY) && has_no_members(qe->parent)) {
 			leave_queue(qe);
 			break;
 		}
@@ -1209,14 +1199,14 @@
 		break;
 	case QUEUE_STRATEGY_ROUNDROBIN:
 		if (!pos) {
-			if (!q->wrapped) {
+			if (!ast_test_flag(q, QUEUE_FLAG_WRAPPED)) {
 				/* No more channels, start over */
 				q->rrpos = 0;
 			} else {
 				/* Prioritize next entry */
 				q->rrpos++;
 			}
-			q->wrapped = 0;
+			ast_clear_flag(q, QUEUE_FLAG_WRAPPED);
 		}
 		/* Fall through */
 	case QUEUE_STRATEGY_RRMEMORY:
@@ -1225,7 +1215,7 @@
 		} else {
 			if (pos > q->rrpos) {
 				/* Indicate there is another priority */
-				q->wrapped = 1;
+				ast_set_flag(q, QUEUE_FLAG_WRAPPED);
 			}
 			tmp->metric = pos;
 		}
@@ -1258,10 +1248,7 @@
 	struct member *cur;
 	struct localuser *outgoing=NULL, *tmp = NULL;
 	int to;
-	int allowredir_in=0;
-	int allowredir_out=0;
-	int allowdisconnect_in=0;
-	int allowdisconnect_out=0;
+	struct localuser flags_dummy;
 	char restofit[AST_MAX_EXTENSION];
 	char oldexten[AST_MAX_EXTENSION]="";
 	char oldcontext[AST_MAX_EXTENSION]="";
@@ -1303,19 +1290,19 @@
 		tmp->stillgoing = -1;
 		if (options) {
 			if (strchr(options, 't'))
-				tmp->allowredirect_in = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_REDIR_IN);
 			if (strchr(options, 'T'))
-				tmp->allowredirect_out = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_REDIR_OUT);
 			if (strchr(options, 'r'))
-				tmp->ringbackonly = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_RINGBACKONLY);
 			if (strchr(options, 'm'))
-				tmp->musiconhold = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_MUSICONHOLD);
 			if (strchr(options, 'd'))
-				tmp->dataquality = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_DATAQUALITY);
 			if (strchr(options, 'h'))
-				tmp->allowdisconnect_in = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_DISCON_IN);
 			if (strchr(options, 'H'))
-				tmp->allowdisconnect_out = 1;
+				ast_set_flag(tmp, QUEUE_FLAG_DISCON_OUT);
 			if ((strchr(options, 'n')) && (now - qe->start >= qe->parent->timeout))
 				*go_on = 1;
 		}
@@ -1358,7 +1345,7 @@
 		to = -1;
 	ring_one(qe, outgoing);
 	ast_mutex_unlock(&qe->parent->lock);
-	lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit);
+	lpeer = wait_for_answer(qe, outgoing, &to, &flags_dummy, &digit);
 	ast_mutex_lock(&qe->parent->lock);
 	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
 		store_next(qe, outgoing);
@@ -1390,11 +1377,11 @@
 		   conversation.  */
 		qe->handled++;
 		if (!strcmp(qe->chan->type,"Zap")) {
-			if (tmp->dataquality) zapx = 0;
+			zapx = !ast_test_flag(tmp, QUEUE_FLAG_DATAQUALITY);
 			ast_channel_setoption(qe->chan,AST_OPTION_TONE_VERIFY,&zapx,sizeof(char),0);
 		}			
 		if (!strcmp(peer->type,"Zap")) {
-			if (tmp->dataquality) zapx = 0;
+			zapx = !ast_test_flag(tmp, QUEUE_FLAG_DATAQUALITY);
 			ast_channel_setoption(peer,AST_OPTION_TONE_VERIFY,&zapx,sizeof(char),0);
 		}
 		/* Update parameters for the queue */
@@ -1402,7 +1389,7 @@
 		member = lpeer->member;
 		hanguptree(outgoing, peer);
 		outgoing = NULL;
-		if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
+		if (announce || ast_test_flag(qe->parent, QUEUE_FLAG_REPORTHOLDTIME) || qe->parent->memberdelay) {
 			int res2;
 			res2 = ast_autoservice_start(qe->chan);
 			if (!res2) {
@@ -1414,7 +1401,7 @@
 					if (play_file(peer, announce))
 						ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", announce);
 				}
-				if (!res2 && qe->parent->reportholdtime) {
+				if (!res2 && ast_test_flag(qe->parent, QUEUE_FLAG_REPORTHOLDTIME)) {
 					if (!play_file(peer, qe->parent->sound_reporthold)) {
 						int holdtime;
 						time_t now;
@@ -1460,7 +1447,7 @@
 			} else {
 				ast_monitor_start( peer, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
 			}
-			if(qe->parent->monjoin) {
+			if(ast_test_flag(qe->parent, QUEUE_FLAG_MONJOIN)) {
 				ast_monitor_setjoinfiles( peer, 1);
 			}
 		}
@@ -1477,11 +1464,11 @@
 		time(&callstart);
 
 		memset(&config,0,sizeof(struct ast_bridge_config));
-        config.allowredirect_in = allowredir_in;
-        config.allowredirect_out = allowredir_out;
-        config.allowdisconnect_in = allowdisconnect_in;
-	config.allowdisconnect_out = allowdisconnect_out;
-        bridge = ast_bridge_call(qe->chan,peer,&config);
+		config.allowredirect_in = ast_test_flag(&flags_dummy, QUEUE_FLAG_REDIR_IN);
+		config.allowredirect_out = ast_test_flag(&flags_dummy, QUEUE_FLAG_REDIR_OUT);
+		config.allowdisconnect_in = ast_test_flag(&flags_dummy, QUEUE_FLAG_DISCON_IN);
+		config.allowdisconnect_out = ast_test_flag(&flags_dummy, QUEUE_FLAG_DISCON_OUT);
+		bridge = ast_bridge_call(qe->chan,peer,&config);
 
 		if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
 			ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s", qe->chan->exten, qe->chan->context);
@@ -2037,7 +2024,7 @@
 				}
 
 				/* leave the queue if no agents, if enabled */
-				if (has_no_members(qe.parent) && (qe.parent->leavewhenempty)) {
+				if (ast_test_flag(qe.parent, QUEUE_FLAG_LEAVEWHENEMPTY) && has_no_members(qe.parent)) {
 					res = 0;
 					break;
 				}
@@ -2121,7 +2108,7 @@
 	/* Mark all queues as dead for the moment */
 	q = queues;
 	while(q) {
-		q->dead = 1;
+		ast_set_flag(q, QUEUE_FLAG_DEAD);
 		q = q->next;
 	}
 	/* Chug through config file */
@@ -2151,7 +2138,7 @@
 				if (!new) 
 					ast_mutex_lock(&q->lock);
 				/* Re-initialize the queue */
-				q->dead = 0;
+				ast_clear_flag(q, QUEUE_FLAG_DEAD);
 				q->retry = 0;
 				q->timeout = -1;
 				q->maxlen = 0;
@@ -2216,7 +2203,7 @@
 					} else if (!strcasecmp(var->name, "timeout")) {
 						q->timeout = atoi(var->value);
 					} else if (!strcasecmp(var->name, "monitor-join")) {
-						q->monjoin = ast_true(var->value);
+						ast_set2_flag(q, ast_true(var->value), QUEUE_FLAG_MONJOIN);
 					} else if (!strcasecmp(var->name, "monitor-format")) {
 						strncpy(q->monfmt, var->value, sizeof(q->monfmt) - 1);
 					} else if (!strcasecmp(var->name, "queue-youarenext")) {
@@ -2262,13 +2249,13 @@
 							q->strategy = 0;
 						}
 					} else if (!strcasecmp(var->name, "joinempty")) {
-						q->joinempty = ast_true(var->value);
+						ast_set2_flag(q, ast_true(var->value), QUEUE_FLAG_JOINEMPTY);
 					} else if (!strcasecmp(var->name, "leavewhenempty")) {
-						q->leavewhenempty = ast_true(var->value);
+						ast_set2_flag(q, ast_true(var->value), QUEUE_FLAG_LEAVEWHENEMPTY);
 					} else if (!strcasecmp(var->name, "eventwhencalled")) {
-						q->eventwhencalled = ast_true(var->value);
+						ast_set2_flag(q, ast_true(var->value), QUEUE_FLAG_EVENTWHENCALLED);
 					} else if (!strcasecmp(var->name, "reportholdtime")) {
-						q->reportholdtime = ast_true(var->value);
+						ast_set2_flag(q, ast_true(var->value), QUEUE_FLAG_REPORTHOLDTIME);
 					} else if (!strcasecmp(var->name, "memberdelay")) {
 						q->memberdelay = atoi(var->value);
 					} else {
@@ -2302,7 +2289,7 @@
 	ql = NULL;
 	while(q) {
 		qn = q->next;
-		if (q->dead) {
+		if (ast_test_flag(q, QUEUE_FLAG_DEAD)) {
 			if (ql)
 				ql->next = q->next;
 			else




More information about the svn-commits mailing list