Index: app_queue.c
===================================================================
--- app_queue.c	(revision 43625)
+++ app_queue.c	(working copy)
@@ -338,7 +338,7 @@
 #define QUEUE_EVENT_VARIABLES 3
 
 struct call_queue {
-	ast_mutex_t lock;	
+	ast_mutex_t lock;
 	char name[80];                      /*!< Name */
 	char moh[80];                       /*!< Music On Hold class to be used */
 	char announce[80];                  /*!< Announcement to play when call is answered */
@@ -391,7 +391,7 @@
 	int rrpos;                          /*!< Round Robin - position */
 	int memberdelay;                    /*!< Seconds to delay connecting member to caller */
 	int autofill;                       /*!< Ignore the head call status and ring an available agent */
-	
+
 	struct member *members;             /*!< Head of the list of members */
 	struct queue_ent *head;             /*!< Head of the list of callers */
 	AST_LIST_ENTRY(call_queue) list;    /*!< Next call queue */
@@ -463,11 +463,13 @@
 	QUEUE_NORMAL
 };
 
-static enum queue_member_status get_member_status(const struct call_queue *q, int max_penalty)
+static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty)
 {
 	struct member *member;
 	enum queue_member_status result = QUEUE_NO_MEMBERS;
 
+	ast_mutex_lock(&q->lock);
+
 	for (member = q->members; member; member = member->next) {
 		if (max_penalty && (member->penalty > max_penalty))
 			continue;
@@ -482,10 +484,12 @@
 			result = QUEUE_NO_REACHABLE_MEMBERS;
 			break;
 		default:
+			ast_mutex_unlock(&q->lock);
 			return QUEUE_NORMAL;
 		}
 	}
-	
+
+	ast_mutex_unlock(&q->lock);
 	return result;
 }
 
@@ -587,7 +591,7 @@
 static struct member *create_queue_member(char *interface, const char *membername, int penalty, int paused)
 {
 	struct member *cur;
-	
+
 	if ((cur = ast_calloc(1, sizeof(*cur)))) {
 		cur->penalty = penalty;
 		cur->paused = paused;
@@ -674,7 +678,7 @@
 
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
-	
+
 	if ((curint = ast_calloc(1, sizeof(*curint)))) {
 		ast_copy_string(curint->interface, interface, sizeof(curint->interface));
 		AST_LIST_INSERT_HEAD(&interfaces, curint, list);
@@ -751,7 +755,7 @@
 	char *c, *lastc;
 	char buff[80];
 
-	if (!strcasecmp(param, "musicclass") || 
+	if (!strcasecmp(param, "musicclass") ||
 		!strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
 		ast_copy_string(q->moh, val, sizeof(q->moh));
 	} else if (!strcasecmp(param, "announce")) {
@@ -1302,7 +1306,7 @@
 				if (res && valid_exit(qe, res))
 					goto playout;
 			}
-			
+
 			res = play_file(qe->chan, qe->parent->sound_minutes);
 			if (res && valid_exit(qe, res))
 				goto playout;
@@ -1392,7 +1396,7 @@
 	}
 	ast_mutex_unlock(&q->lock);
 
-	if (q->dead && !q->count) {	
+	if (q->dead && !q->count) {
 		/* It's dead and nobody is in it, so kill it */
 		AST_LIST_LOCK(&queues);
 		AST_LIST_REMOVE(&queues, q, list);
@@ -1467,7 +1471,7 @@
 	struct call_queue *q;
 	struct member *mem;
 	int found = 0;
-	
+
 	/* &qlock and &rq->lock already set by try_calling()
 	 * to solve deadlock */
 	AST_LIST_TRAVERSE(&queues, q, list) {
@@ -1603,7 +1607,7 @@
 		return 0;
 	} else if (status != tmp->oldstatus)
 		update_dial_status(qe->parent, tmp->member, status);
-	
+
 	tmp->chan->appl = "AppQueue";
 	tmp->chan->data = "(Outgoing Line)";
 	tmp->chan->whentohangup = 0;
@@ -1747,7 +1751,7 @@
 		/* Stop playback */
 		ast_stopstream(chan);
 	}
-	
+
 	return res;
 }
 
@@ -1773,7 +1777,7 @@
 	if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS || !strlen(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound])) {
 		qe->last_periodic_announce_sound = 0;
 	}
-	
+
 	/* play the announcement */
 	res = background_file(qe, qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]);
 
@@ -1786,7 +1790,7 @@
 
 	/* Update the current periodic announcement to the next announcement */
 	qe->last_periodic_announce_sound++;
-	
+
 	return res;
 }
 
@@ -1842,10 +1846,10 @@
 	char on[80] = "";
 	char membername[80] = "";
 	long starttime = 0;
-	long endtime = 0;	
+	long endtime = 0;
 
 	starttime = (long) time(NULL);
-	
+
 	while (*to && !peer) {
 		int numlines, retry, pos = 1;
 		struct ast_channel *watchers[AST_MAX_WATCHERS];
@@ -1913,7 +1917,7 @@
 					/* Setup parameters */
 					o->chan = ast_request(tech, in->nativeformats, stuff, &status);
 					if (status != o->oldstatus)
-						update_dial_status(qe->parent, o->member, status);						
+						update_dial_status(qe->parent, o->member, status);
 					if (!o->chan) {
 						ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
 						o->stillgoing = 0;
@@ -1999,7 +2003,7 @@
 							if (!sentringing) {
 #if 0
 								ast_indicate(in, AST_CONTROL_RINGING);
-#endif								
+#endif
 								sentringing++;
 							}
 							break;
@@ -2076,14 +2080,14 @@
 			if (option_debug)
 				ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
 			res = 0;
-		}	
+		}
 
 	} else {
 		/* This needs a lock. How many members are available to be served? */
 		ast_mutex_lock(&qe->parent->lock);
-			
+
 		ch = qe->parent->head;
-	
+
 		if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
@@ -2101,12 +2105,12 @@
 
 		if (option_debug)
 			ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
-	
+
 		while ((idx < avl) && (ch) && (ch != qe)) {
 			idx++;
-			ch = ch->next;			
+			ch = ch->next;
 		}
-	
+
 		/* If the queue entry is within avl [the number of available members] calls from the top ... */
 		if (ch && idx < avl) {
 			if (option_debug)
@@ -2117,7 +2121,7 @@
 				ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
 			res = 0;
 		}
-		
+
 		ast_mutex_unlock(&qe->parent->lock);
 	}
 
@@ -2278,7 +2282,7 @@
 
 	memset(&bridge_config, 0, sizeof(bridge_config));
 	time(&now);
-		
+
 	for (; options && *options; options++)
 		switch (*options) {
 		case 't':
@@ -2346,7 +2350,7 @@
 			   XXX If we're forcibly removed, these outgoing calls won't get
 			   hung up XXX */
 			tmp->q_next = outgoing;
-			outgoing = tmp;		
+			outgoing = tmp;
 			/* If this line is up, don't try anybody else */
 			if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
 				break;
@@ -2517,7 +2521,7 @@
 					memset(meid, 0, sizeof(meid));
 					pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
 				}
-	
+
 				snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
 
 				mixmonapp = pbx_findapp("MixMonitor");
@@ -2529,7 +2533,7 @@
 
 				if (!monitor_options)
 					monitor_options = "";
-				
+
 				if (strchr(monitor_options, '|')) {
 					ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
 					mixmonapp = NULL;
@@ -2540,7 +2544,7 @@
 						snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
 					else
 						snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
-						
+
 					if (option_debug)
 						ast_log(LOG_DEBUG, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
 
@@ -2552,7 +2556,7 @@
 			}
 		}
 		/* Drop out of the queue at this point, to prepare for next caller */
-		leave_queue(qe);			
+		leave_queue(qe);
 		if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "app_queue: sendurl=%s.\n", url);
@@ -2694,7 +2698,7 @@
 		}
 		value_len += res;
 	}
-	
+
 	if (value_len && !cur_member) {
 		if (ast_db_put(pm_family, pm_queue->name, value))
 			ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
@@ -2736,10 +2740,10 @@
 				"MemberName: %s\r\n",
 				q->name, last_member->interface, last_member->membername);
 			free(last_member);
-			
+
 			if (queue_persistent_members)
 				dump_queue_members(q);
-			
+
 			res = RES_OKAY;
 		} else {
 			res = RES_EXISTS;
@@ -2791,10 +2795,10 @@
 				new_member->dynamic ? "dynamic" : "static",
 				new_member->penalty, new_member->calls, (int) new_member->lastcall,
 				new_member->status, new_member->paused);
-			
+
 			if (dump)
 				dump_queue_members(q);
-			
+
 			res = RES_OKAY;
 		} else {
 			res = RES_OUTOFMEMORY;
@@ -2852,7 +2856,7 @@
 /* Reload dynamic queue members persisted into the astdb */
 static void reload_queue_members(void)
 {
-	char *cur_ptr;	
+	char *cur_ptr;
 	char *queue_name;
 	char *member;
 	char *interface;
@@ -2911,7 +2915,7 @@
 				ast_log(LOG_WARNING, "Error converting penalty: %s: Out of range.\n", penalty_tok);
 				break;
 			}
-			
+
 			if (!paused_tok) {
 				ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (paused)\n", queue_name);
 				break;
@@ -2926,7 +2930,7 @@
 
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Reload Members: Queue: %s  Member: %s  Name: %s  Penalty: %d  Paused: %d\n", queue_name, interface, membername, penalty, paused);
-			
+
 			if (add_to_queue(queue_name, membername, interface, penalty, paused, 0) == RES_OUTOFMEMORY) {
 				ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
 				break;
@@ -3147,7 +3151,7 @@
 			penalty = 0;
 		}
 	}
-	
+
 	if (args.options) {
 		if (strchr(args.options, 'j'))
 			priority_jump = 1;
@@ -3216,7 +3220,7 @@
 		return -1;
 	}
 
-	ast_queue_log(args.queuename, args.uniqueid, args.membername, args.event, 
+	ast_queue_log(args.queuename, args.uniqueid, args.membername, args.event,
 		"%s", args.params ? args.params : "");
 
 	ast_module_user_remove(u);
@@ -3247,12 +3251,12 @@
 	);
 	/* Our queue entry */
 	struct queue_ent qe;
-	
+
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Queue requires an argument: queuename[|options[|URL][|announceoverride][|timeout]]\n");
 		return -1;
 	}
-	
+
 	parse = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, parse);
 
@@ -3468,12 +3472,12 @@
 		}
 		/* Don't allow return code > 0 */
 		if (res >= 0 && res != AST_PBX_KEEPALIVE) {
-			res = 0;	
+			res = 0;
 			if (ringing) {
 				ast_indicate(chan, -1);
 			} else {
 				ast_moh_stop(chan);
-			}			
+			}
 			ast_stopstream(chan);
 		}
 		leave_queue(&qe);
@@ -3497,14 +3501,14 @@
 	struct member *m;
 
 	buf[0] = '\0';
-	
+
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
 		return -1;
 	}
 
 	lu = ast_module_user_add(chan);
-	
+
 	AST_LIST_LOCK(&queues);
 	AST_LIST_TRAVERSE(&queues, q, list) {
 		if (!strcasecmp(q->name, data)) {
@@ -3538,14 +3542,14 @@
 	struct ast_module_user *lu;
 
 	buf[0] = '\0';
-	
+
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
 		return -1;
 	}
 
 	lu = ast_module_user_add(chan);
-	
+
 	AST_LIST_LOCK(&queues);
 	AST_LIST_TRAVERSE(&queues, q, list) {
 		if (!strcasecmp(q->name, data)) {
@@ -3579,7 +3583,7 @@
 		ast_log(LOG_ERROR, "QUEUE_MEMBER_LIST requires an argument: queuename\n");
 		return -1;
 	}
-	
+
 	u = ast_module_user_add(chan);
 
 	AST_LIST_LOCK(&queues);
@@ -3664,7 +3668,7 @@
 		AST_APP_ARG(penalty);
 		AST_APP_ARG(membername);
 	);
-	
+
 	if (!(cfg = ast_config_load("queues.conf"))) {
 		ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
 		return 0;
@@ -3678,7 +3682,7 @@
 	/* Chug through config file */
 	cat = NULL;
 	while ((cat = ast_category_browse(cfg, cat)) ) {
-		if (!strcasecmp(cat, "general")) {	
+		if (!strcasecmp(cat, "general")) {
 			/* Initialize global settings */
 			queue_persistent_members = 0;
 			if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers")))
@@ -3719,7 +3723,7 @@
 					if (!strcasecmp(var->name, "member")) {
 						/* Add a new member */
 						ast_copy_string(parse, var->value, sizeof(parse));
-						
+
 						AST_NONSTANDARD_APP_ARGS(args, parse, ',');
 
 						interface = args.interface;
@@ -3908,7 +3912,7 @@
 			}
 		} else if (s)
 			astman_append(s, "   No Members%s", term);
-		else	
+		else
 			ast_cli(fd, "   No Members%s", term);
 		if (q->head) {
 			pos = 1;
@@ -3958,11 +3962,11 @@
 	char *ret = NULL;
 	int which = 0;
 	int wordlen = strlen(word);
-	
+
 	AST_LIST_LOCK(&queues);
 	AST_LIST_TRAVERSE(&queues, q, list) {
 		if (!strncasecmp(word, q->name, wordlen) && ++which > state) {
-			ret = ast_strdup(q->name);	
+			ret = ast_strdup(q->name);
 			break;
 		}
 	}
