[svn-commits] irroot: branch irroot/asterisk-trunk-quack-queue r344898 - /team/irroot/aster...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Nov 11 17:51:37 CST 2011


Author: irroot
Date: Fri Nov 11 17:51:34 2011
New Revision: 344898

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=344898
Log:
Reverting change from bitield to flag
cleanups
support AST_DEVICE_BUSY

Modified:
    team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c

Modified: team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c?view=diff&rev=344898&r1=344897&r2=344898
==============================================================================
--- team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c (original)
+++ team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c Fri Nov 11 17:51:34 2011
@@ -914,17 +914,6 @@
 	QUEUE_ADD_MEMBER_DYNAMIC = (1 << 2),
 };
 
-enum callattempt_flags {
-	/*! This attempt is busy dialing a user */
-	QUEUE_MEMBER_RESERVED = (1 << 0),
-	/*! This attempt is bridged */
-	QUEUE_MEMBER_ACTIVE = (1 << 1),
-	/*! TRUE if an AST_CONTROL_CONNECTED_LINE update was saved to the connected element. */
-	QUEUE_ATTEMPT_PENDING_CONNECTED = (1 << 2),
-	/*! TRUE if caller id is not available for connected line */
-	QUEUE_ATTEMPT_CALLERID_ABSENT = (1 << 3),
-};
-
 static const struct strategy {
 	int strategy;
 	const char *name;
@@ -1047,14 +1036,15 @@
 */
 
 struct callattempt {
-	struct ast_channel *chan;
-	int stillgoing;
-	int metric;
-	struct member *member;
-	/*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
-	struct ast_party_connected_line connected;
-	/*! Attempt flags */
-	unsigned int flags;
+	struct ast_channel *chan;                  /*! Channel called */
+	int stillgoing;                            /*! This attempt is valid and active */
+	int metric;                                /*! Metric calculated according to strategy */
+	struct member *member;                     /*! Member assosiated with this attempt */
+	struct ast_party_connected_line connected; /*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
+	unsigned int reserved:1;                   /*! Is this attempt been attempted*/
+	unsigned int active:1;                     /*! Is this attempt active in a call*/
+	unsigned int pending_connected_update:1;   /*! TRUE if caller id is not available for connected line*/
+	unsigned int dial_callerid_absent:1;       /*! TRUE if caller id is not available for connected line */
 	struct ast_aoc_decoded *aoc_s_rate_list;
 };
 
@@ -1066,7 +1056,7 @@
 	int prio;                              /*!< Our priority */
 	int last_pos_said;                     /*!< Last position we told the user */
 	int ring_when_ringing;                 /*!< Should we only use ring indication when a channel is ringing? */
-	struct timeval last_periodic_announce_time;    /*!< The last time we played a periodic announcement */
+	struct timeval last_pannounce_time;    /*!< The last time we played a periodic announcement */
 	int last_periodic_announce_sound;      /*!< The last periodic announcement we made */
 	struct timeval last_pos;               /*!< Last time we told the user their position */
 	int opos;                              /*!< Where we started in the queue */
@@ -1088,19 +1078,10 @@
 
 /*! \brief keep track of device state changes */
 struct mem_state {
-	char state_interface[80];            /*!< Technology/Location from which to read devicestate changes */
-	int reserved;                        /*!< This interface is reserved for pending call */
-	int active;                          /*!< This interface is active on a call */
-	int status;                          /*!< Status of queue member */
-};
-
-
-enum member_flags {
-	QUEUE_MEMBER_REALTIME = ( 1 << 0),     /*!< Is this member realtime? */
-	QUEUE_MEMBER_DYNAMIC = ( 1 << 1),      /*!< Is this member dynamic? */
-	QUEUE_MEMBER_DEAD = (1 << 2),          /*!< Used to detect members deleted in realtime */
-	QUEUE_MEMBER_PAUSED = (1 << 3),        /*!< Are we paused (not accepting calls)? */
-	QUEUE_MEMBER_CALLINUSE = ( 1 << 4),    /*!< Are we dynamically added? */
+	char state_interface[80];              /*!< Technology/Location from which to read devicestate changes */
+	int reserved;                          /*!< This interface is reserved for pending call */
+	int active;                            /*!< This interface is active on a call */
+	int status;                            /*!< Status of queue member */
 };
 
 struct member {
@@ -1113,7 +1094,11 @@
 	int calls;                             /*!< Number of calls serviced by this member */
 	struct timeval lastcall;               /*!< When last successful call was hungup */
 	int lastwrapup;                        /*!< Last wrapuptime */
-	unsigned int flags;                    /*!< Member Flags */
+	unsigned int dynamic:1;                /*!< Is this member dynamic? */
+	unsigned int realtime:1;               /*!< Is this member realtime? */
+	unsigned int paused:1;                 /*!< Are we paused (not accepting calls)? */
+	unsigned int dead:1;                   /*!< Used to detect members deleted in realtime */
+	unsigned int callinuse:1;              /*!< Are we dynamically added? */
 	struct mem_state *device;              /*!< Device information */
 };
 
@@ -1215,8 +1200,8 @@
 	int periodicannouncefrequency;      /*!< How often to play periodic announcement */
 	int numperiodicannounce;            /*!< The number of periodic announcements configured */
 	int randomperiodicannounce;         /*!< Are periodic announcments randomly chosen */
+	int roundingseconds;                /*!< How many seconds do we round to? */
 	int servicelevel;                   /*!< seconds setting for servicelevel*/
-	int roundingseconds;                /*!< How many seconds do we round to? */
 	char monfmt[8];                     /*!< Format to use when recording calls */
 	int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
 	int maxlen;                         /*!< Max number of entries */
@@ -1417,12 +1402,31 @@
 	struct mem_state *s = m->device;
 
 	ao2_lock(s);
-	if (s->active && ((s->status == AST_DEVICE_NOT_INUSE) || (s->status == AST_DEVICE_UNKNOWN))) {
-		ret = (ast_test_flag(m, QUEUE_MEMBER_CALLINUSE)) ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
-	} else if (s->reserved && ((s->status == AST_DEVICE_NOT_INUSE) || (s->status == AST_DEVICE_UNKNOWN))) {
-		ret = AST_DEVICE_RINGING;
-	} else {
-		ret = s->status;
+
+	ret = s->status;
+	switch (s->status) {
+		case AST_DEVICE_INVALID:
+		case AST_DEVICE_UNAVAILABLE:
+		case AST_DEVICE_BUSY:
+			break;
+		case AST_DEVICE_INUSE:
+		case AST_DEVICE_RINGING:
+		case AST_DEVICE_RINGINUSE:
+		case AST_DEVICE_ONHOLD:
+			/* if im active and may not place calls when INUSE im actually BUSY */
+			if ((s->reserved || s->active) && !m->callinuse) {
+				ret = AST_DEVICE_BUSY;
+				break;
+			}
+			break;
+		case AST_DEVICE_NOT_INUSE:
+		case AST_DEVICE_UNKNOWN:
+			/* it seems that i have this device active but the system does not */
+			if (s->active) {
+				ret = (m->callinuse) ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
+			} else if (s->reserved) {
+				ret = (m->callinuse) ? AST_DEVICE_RINGING : AST_DEVICE_BUSY;
+			}
 	}
         ao2_unlock(s);
 
@@ -1476,6 +1480,7 @@
 			}
 			goto default_case;
 		case AST_DEVICE_INUSE:
+		case AST_DEVICE_BUSY:
 			if (conditions & QUEUE_EMPTY_INUSE) {
 				ast_debug(4, "%s is unavailable because his device state is 'inuse'\n", member->membername);
 				break;
@@ -1495,7 +1500,7 @@
 			/* Fall-through */
 		default:
 		default_case:
-			if (ast_test_flag(member, QUEUE_MEMBER_PAUSED) && (conditions & QUEUE_EMPTY_PAUSED)) {
+			if (member->paused && (conditions & QUEUE_EMPTY_PAUSED)) {
 				ast_debug(4, "%s is unavailable because he is paused'\n", member->membername);
 				break;
 			} else if ((conditions & QUEUE_EMPTY_WRAPUP) && !ast_tvzero(member->lastcall) && member->lastwrapup && (ast_tvdiff_sec(ast_tvnow(), member->lastcall) <= member->lastwrapup)) {
@@ -1568,11 +1573,8 @@
 				"Status: %d\r\n"
 				"Paused: %d\r\n"
 				"CallInuse: %d\r\n",
-				q->name, m->interface, m->membername, s->state_interface, 
-				(ast_test_flag(m, QUEUE_MEMBER_DYNAMIC)) ? "dynamic" : (ast_test_flag(m, QUEUE_MEMBER_REALTIME)) ? "realtime" : "static",
-				m->penalty, m->calls, (int)m->lastcall.tv_sec, s->status, 
-				ast_test_flag(m, QUEUE_MEMBER_PAUSED) ? 1 : 0,
-				ast_test_flag(m, QUEUE_MEMBER_CALLINUSE) ? 1 : 0
+				q->name, m->interface, m->membername, s->state_interface, m->dynamic ? "dynamic" : m->realtime ? "realtime" : "static",
+				m->penalty, m->calls, (int)m->lastcall.tv_sec, s->status, m->paused, m->callinuse
 			);
 			ao2_unlock(s);
 			ao2_unlock(m);
@@ -1790,7 +1792,7 @@
 	const struct member *mem2 = arg;
 	const char *uniqueid = (flags & OBJ_POINTER) ? mem2->rt_uniqueid : arg;
 
-	if (ast_test_flag(mem1, QUEUE_MEMBER_REALTIME) && !ast_test_flag(mem1, QUEUE_MEMBER_DEAD) &&
+	if (mem1->realtime && !mem1->dead &&
 	    !strcasecmp(mem1->rt_uniqueid, uniqueid)) {
 		return CMP_MATCH | CMP_STOP;
 	}
@@ -1805,10 +1807,8 @@
 {
 	struct member *member = obj;
 
-	if (ast_test_flag(member, QUEUE_MEMBER_REALTIME)) {
-		ao2_lock(member);
-		ast_set_flag(member, QUEUE_MEMBER_DEAD);
-		ao2_unlock(member);
+	if (member->realtime) {
+		member->dead = 1;
 		return CMP_MATCH;
 	}
 	return 0;
@@ -1822,7 +1822,7 @@
 	struct member *m = obj;
 	const struct call_queue *q = data;
 
-	if (ast_test_flag(m, QUEUE_MEMBER_DEAD) && ast_test_flag(m, QUEUE_MEMBER_REALTIME)) {
+	if (m->realtime && m->dead) {
 		ao2_lock(m);
 		if (ast_strlen_zero(m->membername) || !log_membername_as_agent) {
 			ast_queue_log(q->name, "REALTIME", m->interface, "REMOVEMEMBER", "%s", "");
@@ -2030,7 +2030,7 @@
 	}
 
 	q->reload = ast_tvnow();
-	q->reload.tv_sec += 86400; 
+	q->reload.tv_sec += 86400;
 }
 
 /*!
@@ -2382,18 +2382,18 @@
 		}
 		if (ast_string_field_init(m, 64)) {
 			ao2_ref(m, -1);
-			ast_log(LOG_WARNING, "Unable to alocate memory\n");
 			return RES_OUTOFMEMORY;
 		}
 
 		m->device = NULL;
-		m->flags = 0;
-		ast_set_flag(m, QUEUE_MEMBER_CALLINUSE);
+		m->paused = 0;
+		m->callinuse = 1;
 		if (memtype & QUEUE_ADD_MEMBER_REALTIME) {
-			ast_set_flag(m, QUEUE_MEMBER_REALTIME);
+			m->realtime = 1;
 		} else if (memtype & QUEUE_ADD_MEMBER_DYNAMIC) {
-			ast_set_flag(m, QUEUE_MEMBER_DYNAMIC);
-		}
+			m->dynamic = 1;
+		}
+		m->dead = 0;
 		m->calls = 0;
 		m->lastcall = ast_tv(0, 0);
 		m->lastwrapup = 0;
@@ -2404,7 +2404,7 @@
 
 		if (memtype & QUEUE_ADD_MEMBER_DYNAMIC) {
 			/* dynamic members are the lowest priority and cannot overwrite settings from DB*/
-			if (ast_test_flag(m, QUEUE_MEMBER_DYNAMIC)) {
+			if (m->dynamic) {
 				res = RES_EXISTS;
 			} else {
 				res = RES_NOT_DYNAMIC;
@@ -2412,31 +2412,31 @@
 			ao2_unlock(q->data->members);
 			ao2_ref(m, -1);
 			return res;
-		} else if ((ast_test_flag(m, QUEUE_MEMBER_DYNAMIC) || ast_test_flag(m, QUEUE_MEMBER_REALTIME)) &&
-			   (memtype & QUEUE_ADD_MEMBER_STATIC)) {
+		} else if ((m->dynamic || m->realtime) && (memtype & QUEUE_ADD_MEMBER_STATIC)) {
 			/*static members take precedence over all others*/
 			ao2_lock(m);
-			ast_clear_flag(m, QUEUE_MEMBER_DYNAMIC);
-			ast_clear_flag(m, QUEUE_MEMBER_REALTIME);
+			m->dynamic = 0;
+			m->realtime = 0;
 			if (!ast_strlen_zero(m->rt_uniqueid)) {
 				ast_string_field_set(m, rt_uniqueid, NULL);
 			}
 		} else if (memtype & QUEUE_ADD_MEMBER_REALTIME) {
 			/* realtime takes precedence over dynamic but not static*/
 			ao2_lock(m);
-			if (ast_test_flag(m, QUEUE_MEMBER_DYNAMIC)) {
-				ast_clear_flag(m, QUEUE_MEMBER_DYNAMIC);
-				ast_set_flag(m, QUEUE_MEMBER_REALTIME);
-			} else if (!ast_test_flag(m, QUEUE_MEMBER_REALTIME)) {
+			if (m->dynamic) {
+				m->dynamic = 0;
+				m->realtime = 1;
+			} else if (!m->realtime) {
+				ao2_unlock(m);
 				ao2_unlock(q->data->members);
-				ao2_unlock(m);
 				ao2_ref(m, -1);
 				return RES_EXISTS;
 			}
-			ast_clear_flag(m, QUEUE_MEMBER_DEAD);
+			m->dead = 0;
 		} else {
 			ao2_lock(m);
 		}
+		ao2_unlock(q->data->members);
 	}
 
 	for (v = ast_variable_browse(member_config, interface); v; v = v->next) {
@@ -2454,22 +2454,10 @@
 				dead = 1;
 			}
 		} else if (!strcasecmp(v->name, "paused")) {
-			if (ast_true(v->value)) {
-				ast_set_flag(m, QUEUE_MEMBER_PAUSED);
-			} else {
-				ast_clear_flag(m, QUEUE_MEMBER_PAUSED);
-			}
+			m->paused = abs(ast_true(v->value));
 		} else if (!strcasecmp(v->name, "callinuse") || !strcasecmp(v->name, "ignorebusy")) {
-			if (ast_true(v->value)) {
-				ast_set_flag(m, QUEUE_MEMBER_CALLINUSE);
-			} else {
-				ast_clear_flag(m, QUEUE_MEMBER_CALLINUSE);
-			}
-		}
-	}
-
-	if (!link) {
-		ao2_unlock(q->data->members);
+			m->callinuse = abs(ast_true(v->value));
+		}
 	}
 
 	if (ast_strlen_zero(st_dev)) {
@@ -2512,31 +2500,29 @@
 	}
 
 	if (!dead && link) {
+		int status = get_device_status(m);
+
 		/* i have just been born */
 		if ((ast_strlen_zero(m->membername) || !log_membername_as_agent)) {
 			ast_queue_log(q->name, source, m->interface, "ADDMEMBER", "%s", "");
 		} else {
 			ast_queue_log(q->name, source, m->membername, "ADDMEMBER", "%s", "");
 		}
-		if (ast_test_flag(m, QUEUE_MEMBER_DYNAMIC)) {
-			int status = get_device_status(m);
-			manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
-				"Queue: %s\r\n"
-				"Location: %s\r\n"
-				"MemberName: %s\r\n"
-				"StateInterface: %s\r\n"
-				"Membership: %s\r\n"
-				"Penalty: %d\r\n"
-				"CallsTaken: %d\r\n"
-				"LastCall: %d\r\n"
-				"Status: %d\r\n"
-				"Paused: %d\r\n"
-				"CallInuse: %d\r\n",
-				q->name, m->interface, m->membername, m->device->state_interface,
-				"dynamic",m->penalty, m->calls, (int)m->lastcall.tv_sec,
-				status, ast_test_flag(m, QUEUE_MEMBER_PAUSED) ? 1 : 0,
-				ast_test_flag(m, QUEUE_MEMBER_CALLINUSE) ? 1 : 0);
-		}
+		manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
+			"Queue: %s\r\n"
+			"Location: %s\r\n"
+			"MemberName: %s\r\n"
+			"StateInterface: %s\r\n"
+			"Membership: %s\r\n"
+			"Penalty: %d\r\n"
+			"CallsTaken: %d\r\n"
+			"LastCall: %d\r\n"
+			"Status: %d\r\n"
+			"Paused: %d\r\n"
+			"CallInuse: %d\r\n",
+			q->name, m->interface, m->membername, m->device->state_interface,
+			m->dynamic ? "dynamic" : m->realtime ? "realtime" : "static",
+			m->penalty, m->calls, (int)m->lastcall.tv_sec, status, m->paused, m->callinuse);
 		ao2_link(q->data->members, m);
 	} else if (dead) {
 		/* ive failed penalty/uniqueid/devstate failure */
@@ -3213,14 +3199,14 @@
 	struct mem_state *s;
 
 	if (doomed->member) {
-		if (doomed->flags & (QUEUE_MEMBER_RESERVED | QUEUE_MEMBER_ACTIVE)) {
+		if (doomed->reserved || doomed->active) {
 			ao2_lock(doomed->member);
 			s = doomed->member->device;
 			ao2_lock(s);
-			if (ast_test_flag(doomed, QUEUE_MEMBER_RESERVED)) {
+			if (doomed->reserved) {
 				s->reserved--;
 			}
-			if (ast_test_flag(doomed, QUEUE_MEMBER_ACTIVE)) {
+			if (doomed->active) {
 				s->active--;
 			}
 			ao2_unlock(s);
@@ -3247,7 +3233,7 @@
 			}
 			ast_hangup(outgoing->chan);
 			ao2_unlink(qe->attempts, outgoing);
-		} else {
+		} else if (outgoing != exception) {
 			ao2_unlink(qe->attempts, outgoing);
 		}
 		ast_aoc_destroy_decoded(outgoing->aoc_s_rate_list);
@@ -3282,13 +3268,13 @@
 			case AST_DEVICE_RINGING:
 			case AST_DEVICE_RINGINUSE:
 			case AST_DEVICE_ONHOLD:
-				if ((!q->ringinuse) || (!ast_test_flag(mem, QUEUE_MEMBER_CALLINUSE))) {
+				if (!q->ringinuse || !mem->callinuse) {
 					break;
 				}
 				/* else fall through */
 			case AST_DEVICE_NOT_INUSE:
 			case AST_DEVICE_UNKNOWN:
-				if (!ast_test_flag(mem, QUEUE_MEMBER_PAUSED)) {
+				if (!mem->paused) {
 					avl++;
 				}
 				break;
@@ -3412,10 +3398,12 @@
  * Does error checking before attempting to request a channel and call a member. 
  * This function is only called from ring_one(). 
  * Failure can occur if:
- * - Agent on call
- * - Agent is paused
+ * - Priority by another queue
  * - Wrapup time not expired
- * - Priority by another queue
+ * - Member is paused 
+ * - Member on call / or is not available for a call
+ * - Channel cannot be created by driver
+ * - Channel cannot be called by driver
  *
  * \retval 1 on success to reach a free agent
  * \retval 0 on failure to get agent.
@@ -3430,20 +3418,32 @@
 	struct mem_state *s;
 	int dstat;
 
+	/* we cannot take this call there is a more urgent call we qualify for */
+	if (use_weight && compare_weight(qe->parent,tmp->member->interface)) {
+		ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->member->interface);
+		if (qe->chan->cdr) {
+			ast_cdr_busy(qe->chan->cdr);
+		}
+		tmp->stillgoing = 0;
+		(*busies)++;
+		return 0;
+	}
+
 	ao2_lock(tmp->member);
 	s = tmp->member->device;
 
-	/* on entry here, we know that tmp->chan == NULL */
-	if (ast_test_flag(tmp->member, QUEUE_MEMBER_PAUSED)) {
+	if (tmp->member->paused) {
 		ao2_unlock(tmp->member);
 		ast_debug(1, "%s paused, can't receive call\n", tmp->member->interface);
 		if (qe->chan->cdr) {
 			ast_cdr_busy(qe->chan->cdr);
 		}
 		tmp->stillgoing = 0;
+		(*busies)++;
 		return 0;
 	}
 
+	/* am i still in wrapuptime */
 	if (tmp->member->lastwrapup && (ast_tvdiff_sec(ast_tvnow(), tmp->member->lastcall) <= tmp->member->lastwrapup)) {
 		ao2_unlock(tmp->member);
 		ast_debug(1, "Wrapuptime not yet expired for %s\n", tmp->member->interface);
@@ -3455,47 +3455,30 @@
 		return 0;
 	}
 
-	if (!qe->parent->ringinuse || !ast_test_flag(tmp->member, QUEUE_MEMBER_CALLINUSE)) {
-		dstat = get_device_status(tmp->member);
-		if ((dstat == AST_DEVICE_NOT_INUSE) || (dstat == AST_DEVICE_UNKNOWN)) {
-			int newstate = set_queue_member_status(tmp->member);
-			if (newstate != dstat) {
-				ast_log(AST_LOG_WARNING, "Device (%s) state changed from %s to %s\n",
-					tmp->member->interface, ast_devstate2str(dstat), ast_devstate2str(newstate));
-				dstat = newstate;
-			}
-		}
-		if ((dstat != AST_DEVICE_NOT_INUSE) && (dstat != AST_DEVICE_UNKNOWN)) {
-			ao2_unlock(tmp->member);
-			ast_debug(1, "%s in use, can't receive call\n", tmp->member->interface);
-			if (qe->chan->cdr) {
-				ast_cdr_busy(qe->chan->cdr);
-			}
-			tmp->stillgoing = 0;
-			(*busies)++;
-			return 0;
-		}
+	/* do not ring a member that is not able to take a call */
+	dstat = get_device_status(tmp->member);
+	if ((dstat == AST_DEVICE_INVALID) || 
+	    (dstat == AST_DEVICE_BUSY) || 
+	    (dstat == AST_DEVICE_UNAVAILABLE) || 
+	    (!qe->parent->ringinuse && (dstat != AST_DEVICE_NOT_INUSE) && (dstat != AST_DEVICE_UNKNOWN))) {
+		ao2_unlock(tmp->member);
+		ast_debug(1, "%s is %s, can't receive call\n", tmp->member->interface, ast_devstate2str(dstat));
+		if (qe->chan->cdr) {
+			ast_cdr_busy(qe->chan->cdr);
+		}
+		tmp->stillgoing = 0;
+		(*busies)++;
+		return 0;
 	}
 
 	/* mark device and call entry reserved */
-	if (!ast_test_flag(tmp, QUEUE_MEMBER_RESERVED)) {
+	if (!tmp->reserved) {
 		ao2_lock(s);
 		s->reserved++;
 		ao2_unlock(s);
-		ast_set_flag(tmp, QUEUE_MEMBER_RESERVED);
+		tmp->reserved = 1;
 	}
 	ao2_unlock(tmp->member);
-
-	if (use_weight && compare_weight(qe->parent,tmp->member->interface)) {
-		ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->member->interface);
-		if (qe->chan->cdr) {
-			ast_cdr_busy(qe->chan->cdr);
-		}
-		tmp->stillgoing = 0;
-		(*busies)++;
-		return 0;
-	}
-
 
 	ast_copy_string(tech, tmp->member->interface, sizeof(tech));
 	if ((location = strchr(tech, '/'))) {
@@ -3522,10 +3505,7 @@
 		return 0;
 	}
 
-	ast_channel_lock(tmp->chan);
-	while (ast_channel_trylock(qe->chan)) {
-		CHANNEL_DEADLOCK_AVOIDANCE(tmp->chan);
-	}
+	ast_channel_lock_both(tmp->chan, qe->chan);
 
 	if (qe->cancel_answered_elsewhere) {
 		ast_set_flag(tmp->chan, AST_FLAG_ANSWERED_ELSEWHERE);
@@ -3548,7 +3528,7 @@
 		} else if (!ast_strlen_zero(S_OR(qe->chan->macroexten, qe->chan->exten))) {
 			ast_set_callerid(tmp->chan, S_OR(qe->chan->macroexten, qe->chan->exten), NULL, NULL); 
 		}
-		ast_set_flag(tmp, QUEUE_ATTEMPT_CALLERID_ABSENT);
+		tmp->dial_callerid_absent = 1;
 	}
 
 	ast_party_redirecting_copy(&tmp->chan->redirecting, &qe->chan->redirecting);
@@ -3588,20 +3568,22 @@
 		strcpy(tmp->chan->cdr->userfield, qe->chan->cdr->userfield);
 	}
 
+	ast_channel_unlock(tmp->chan);
+	ast_channel_unlock(qe->chan);
+
 	/* Place the call, but don't wait on the answer */
 	if ((res = ast_call(tmp->chan, location, 0))) {
-		/* Again, keep going even if there's an error */
 		ast_debug(1, "ast call on peer returned %d\n", res);
 		ast_verb(3, "Couldn't call %s\n", tmp->member->interface);
-		ast_channel_unlock(tmp->chan);
-		ast_channel_unlock(qe->chan);
 		do_hang(tmp);
 		(*busies)++;
+		tmp->stillgoing = 0;
 		set_queue_member_status(tmp->member);
 		return 0;
 	} else if (qe->parent->eventwhencalled) {
 		char vars[2048];
 
+		ast_channel_lock_both(tmp->chan, qe->chan);
 		ao2_lock(tmp->member);
 		manager_event(EVENT_FLAG_AGENT, "AgentCalled",
 			"Queue: %s\r\n"
@@ -3625,11 +3607,13 @@
 			S_COR(tmp->chan->connected.id.name.valid, tmp->chan->connected.id.name.str, "unknown"),
 			qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
 			qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
+
 		ao2_unlock(tmp->member);
+		ast_channel_unlock(tmp->chan);
+		ast_channel_unlock(qe->chan);
+
 		ast_verb(3, "Called %s\n", tmp->member->interface);
 	}
-	ast_channel_unlock(tmp->chan);
-	ast_channel_unlock(qe->chan);
 
 	return 1;
 }
@@ -3668,13 +3652,12 @@
 				ao2_ref(cur, -1);
 			}
 			ao2_iterator_destroy(&aiter);
-			ao2_ref(best, -1);
 		} else {
 			/* Ring just the best channel */
 			ast_debug(1, "Trying '%s' with metric %d\n", best->member->interface, best->metric);
 			ret = ring_entry(qe, best, busies);
-			ao2_ref(best, -1);
-		}
+		}
+		ao2_ref(best, -1);
 
 		/* If we have timed out, break out */
 		if (!ast_tvzero(qe->expire) && (ast_tvcmp(ast_tvnow(), qe->expire) >= 0)) {
@@ -3688,7 +3671,6 @@
 }
 
 /*! \brief Search for best metric and add to Round Robbin queue
- * \note the members container is locked here for new_attempt
  */
 static int store_next_rr(struct queue_ent *qe)
 {
@@ -3755,7 +3737,7 @@
 	now = ast_tvnow();
 
 	/* Check to see if it is time to announce */
-	if (ast_tvdiff_sec(now, qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency) {
+	if (ast_tvdiff_sec(now, qe->last_pannounce_time) < qe->parent->periodicannouncefrequency) {
 		return 0;
 	}
 
@@ -3789,11 +3771,11 @@
 		}
 	}
 
-	/* update last_periodic_announce_time */
+	/* update last_pannounce_time */
 	if (qe->parent->relativeperiodicannounce) {
-		qe->last_periodic_announce_time = ast_tvnow();
+		qe->last_pannounce_time = ast_tvnow();
 	} else {
-		qe->last_periodic_announce_time = now;
+		qe->last_pannounce_time = now;
 	}
 
 	/* Update the current periodic announcement to the next announcement */
@@ -3863,7 +3845,6 @@
 			}
 		}
 		if (qe->parent->autopause == QUEUE_AUTOPAUSE_ON) {
-			ao2_lock(qe->parent->data->members);
 			ao2_lock(call->member);
 			if (!(do_set_member_penalty_paused(qe->parent, call->member, 1, 1, "Auto-Pause"))) {
 				ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n",
@@ -3872,7 +3853,6 @@
 				ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", call->member->interface, qe->parent->name);
 			}
 			ao2_unlock(call->member);
-			ao2_unlock(qe->parent->data->members);
 		} else {
 			/* If queue autopause is mode all, just don't send any queue to stop.
 			* the function will stop in all queues */
@@ -4010,11 +3990,11 @@
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
 					if (update_connectedline) {
-						if (ast_test_flag(o, QUEUE_ATTEMPT_PENDING_CONNECTED)) {
+						if (o->pending_connected_update) {
 							if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 								ast_channel_update_connected_line(in, &o->connected, NULL);
 							}
-						} else if (!ast_test_flag(o, QUEUE_ATTEMPT_CALLERID_ABSENT)) {
+						} else if (!o->dial_callerid_absent) {
 							ast_channel_lock(o->chan);
 							ast_connected_line_copy_from_caller(&connected_caller, &o->chan->caller);
 							ast_channel_unlock(o->chan);
@@ -4078,10 +4058,8 @@
 					} else {
 						struct ast_party_redirecting redirecting;
 
-						ast_channel_lock(o->chan);
-						while (ast_channel_trylock(in)) {
-							CHANNEL_DEADLOCK_AVOIDANCE(o->chan);
-						}
+						ast_channel_lock_both(o->chan, in);
+
 						ast_channel_inherit_variables(in, o->chan);
 						ast_channel_datastore_inherit(in, o->chan);
 
@@ -4164,11 +4142,11 @@
 					if (!peer) {
 						ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
 						if (update_connectedline) {
-							if (ast_test_flag(o, QUEUE_ATTEMPT_PENDING_CONNECTED)) {
+							if (o->pending_connected_update) {
 								if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
 									ast_channel_update_connected_line(in, &o->connected, NULL);
 								}
-							} else if (!ast_test_flag(o, QUEUE_ATTEMPT_CALLERID_ABSENT)) {
+							} else if (!o->dial_callerid_absent) {
 								ast_channel_lock(o->chan);
 								ast_connected_line_copy_from_caller(&connected_caller, &o->chan->caller);
 								ast_channel_unlock(o->chan);
@@ -4253,7 +4231,7 @@
 						ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
 						ast_party_connected_line_set(&o->connected, &connected, NULL);
 						ast_party_connected_line_free(&connected);
-						ast_set_flag(o, QUEUE_ATTEMPT_PENDING_CONNECTED);
+						o->pending_connected_update = 1;
 					} else {
 						if (ast_channel_connected_line_macro(o->chan, in, f, 1, 1)) {
 							ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
@@ -4287,7 +4265,6 @@
 				}
 				ast_frfree(f);
 			}
-			/* hold a ref for the answerd line */
 			ao2_ref(o, -1);
 		}
 		ao2_iterator_destroy(&aiter);
@@ -4661,7 +4638,8 @@
 
 	tmp->stillgoing = -1;
 	tmp->member = mem;/* Place the reference for cur into callattempt. */
-	tmp->flags = 0;
+	tmp->dial_callerid_absent = 0;
+	tmp->pending_connected_update =0;
 	tmp->metric = metric;
 
 	return tmp;
@@ -4755,6 +4733,7 @@
 				(long)ast_tvdiff_sec(ast_tvnow(), callstart), qe->opos);
 
 	ao2_unlock(member);
+
 	update_queue(qe->parent, member, callcompletedinsl, ast_tvdiff_sec(ast_tvnow(), callstart));
 
 	/* No need to lock the channels because they are already locked in ast_do_masquerade */
@@ -4840,8 +4819,6 @@
  *    iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
  *    member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
  *    during each iteration, we calculate a metric to determine which members should be rung when.
- * \note It is too costly to lock and unlock the queue and members for this and the queue and members container
- * Is locked for the whole process.
  *
  * 3. Call ring_one to place a call to the appropriate member(s)
  * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
@@ -5227,6 +5204,7 @@
 				ast_queue_log(qe->parent->name, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)ast_tvdiff_sec(ast_tvnow(), qe->start));
 				ao2_unlock(member);
 				record_abandoned(qe);
+				ao2_unlink(qe->attempts, lpeer);
 				ao2_ref(lpeer, -1);
 				ast_hangup(peer);
 				return -1;
@@ -5250,6 +5228,7 @@
 			ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
 			record_abandoned(qe);
 			ast_cdr_failed(qe->chan->cdr);
+			ao2_unlink(qe->attempts, lpeer);
 			ao2_ref(lpeer, -1);
 			ast_hangup(peer);
 			return -1;
@@ -5266,9 +5245,7 @@
 		if (qe->parent->setinterfacevar) {
 			ao2_lock(member);
 			snprintf(interfacevar, sizeof(interfacevar), "MEMBERINTERFACE=%s,MEMBERNAME=%s,MEMBERCALLS=%d,MEMBERLASTCALL=%ld,MEMBERPENALTY=%d,MEMBERDYNAMIC=%d,MEMBERREALTIME=%d",
-				member->interface, member->membername, member->calls, (long)member->lastcall.tv_sec, member->penalty,
-				ast_test_flag(member, QUEUE_MEMBER_DYNAMIC),
-				ast_test_flag(member, QUEUE_MEMBER_REALTIME));
+				member->interface, member->membername, member->calls, (long)member->lastcall.tv_sec, member->penalty, member->dynamic, member->realtime);
 			pbx_builtin_setvar_multiple(qe->chan, interfacevar);
 			pbx_builtin_setvar_multiple(peer, interfacevar);
 			ao2_unlock(member);
@@ -5536,41 +5513,6 @@
 				ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
 		}
 		qe->handled++;
-		ao2_lock(member);
-		ast_queue_log(qe->parent->name, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld",
-					(long)ast_tvdiff_sec(ast_tvnow(), qe->start), peer->uniqueid,
-					(long)(orig - to > 0 ? (orig - to) / 1000 : 0));
-		ao2_unlock(member);
-
-		if (qe->chan->cdr) {
-			struct ast_cdr *cdr;
-			struct ast_cdr *newcdr;
-
-			/* Only work with the last CDR in the stack*/
-			cdr = qe->chan->cdr;
-			while (cdr->next) {
-				cdr = cdr->next;
-			}
-
-			/* If this CDR is not related to us add new one*/
-			if ((strcasecmp(cdr->uniqueid, qe->chan->uniqueid)) &&
-			    (strcasecmp(cdr->linkedid, qe->chan->uniqueid)) &&
-			    (newcdr = ast_cdr_dup(cdr))) {
-				ast_cdr_init(newcdr, qe->chan);
-				ast_cdr_reset(newcdr, 0);
-				ast_channel_lock(qe->chan);
-				cdr = ast_cdr_append(cdr, newcdr);
-				cdr = cdr->next;
-				ast_channel_unlock(qe->chan);
-			}
-
-			if (update_cdr) {
-				ao2_lock(member);
-				ast_copy_string(cdr->dstchannel, member->membername, sizeof(cdr->dstchannel));
-				ao2_unlock(member);
-			}
-		}
-
 		callstart = ast_tvnow();
 
 		ao2_lock(member);
@@ -5589,7 +5531,40 @@
 					(long)ast_tvdiff_sec(callstart, qe->start), peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
 					qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
 		}
+
+		ast_queue_log(qe->parent->name, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld",
+					(long)ast_tvdiff_sec(ast_tvnow(), qe->start), peer->uniqueid,
+					(long)(orig - to > 0 ? (orig - to) / 1000 : 0));
 		ao2_unlock(member);
+
+		if (qe->chan->cdr) {
+			struct ast_cdr *cdr;
+			struct ast_cdr *newcdr;
+
+			/* Only work with the last CDR in the stack*/
+			cdr = qe->chan->cdr;
+			while (cdr->next) {
+				cdr = cdr->next;
+			}
+
+			/* If this CDR is not related to us add new one*/
+			if ((strcasecmp(cdr->uniqueid, qe->chan->uniqueid)) &&
+			    (strcasecmp(cdr->linkedid, qe->chan->uniqueid)) &&
+			    (newcdr = ast_cdr_dup(cdr))) {
+				ast_cdr_init(newcdr, qe->chan);
+				ast_cdr_reset(newcdr, 0);
+				ast_channel_lock(qe->chan);
+				cdr = ast_cdr_append(cdr, newcdr);
+				cdr = cdr->next;
+				ast_channel_unlock(qe->chan);
+			}
+
+			if (update_cdr) {
+				ao2_lock(member);
+				ast_copy_string(cdr->dstchannel, member->membername, sizeof(cdr->dstchannel));
+				ao2_unlock(member);
+			}
+		}
 
 		ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
 		ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
@@ -5607,21 +5582,28 @@
 			ao2_t_ref(qe->parent, 1, "For bridge_config reference");
 		}
 
-		ast_channel_lock(peer);
+		/* The call was picked up elsewhere log the original interface the channel picking up the call hold time and position */
+		ast_channel_lock_both(peer, qe->chan);
 		if (ast_channel_datastore_find(peer, &pickup_target_info, NULL)) {
-			ast_channel_unlock(peer);
 			ao2_unlink(qe->attempts, lpeer);
 			ao2_ref(member, 1);
+			ao2_lock(member);
+			ast_queue_log(qe->parent->name, qe->chan->uniqueid, member->membername, "PICKUP", "%s|%s|%ld|%d",
+						member->interface, peer->name, (long)ast_tvdiff_sec(callstart, qe->start), qe->opos);
+			ao2_unlock(member);
 			ao2_ref(lpeer, -1);
 			lpeer = NULL;
+			ast_channel_unlock(peer);
+			ast_channel_unlock(qe->chan);
 		} else {
 			ast_channel_unlock(peer);
+			ast_channel_unlock(qe->chan);
 			ao2_lock(member);
 			ao2_lock(member->device);
 			member->device->active++;
-			ast_set_flag(lpeer, QUEUE_MEMBER_ACTIVE);
-			if (ast_test_flag(lpeer, QUEUE_MEMBER_RESERVED)) {
-				ast_clear_flag(lpeer, QUEUE_MEMBER_RESERVED);
+			lpeer->active = 1;
+			if (lpeer->reserved) {
+				lpeer->reserved = 0;
 				member->device->reserved--;
 			}
 			ao2_unlock(member->device);
@@ -5690,7 +5672,6 @@
 
 static int wait_a_bit(struct queue_ent *qe)
 {
-	/* Don't need to hold the lock while we setup the outgoing calls */
 	int retrywait = qe->parent->retry * 1000;
 
 	int res = ast_waitfordigit(qe->chan, retrywait);
@@ -5745,19 +5726,15 @@
 	mem_iter = ao2_iterator_init(pm_queue->data->members, 0);
 	while ((cur_member = ao2_iterator_next(&mem_iter))) {
 		ao2_lock(cur_member);
-		if (!ast_test_flag(cur_member, QUEUE_MEMBER_DYNAMIC) ||
-		    ast_test_flag(cur_member, QUEUE_MEMBER_DEAD)) {
+		if (!cur_member->dynamic || cur_member->dead) {
 			ao2_unlock(cur_member);
 			ao2_ref(cur_member, -1);
 			continue;
 		}
 
 		res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s;%s;%d",
-			value_len ? "|" : "", cur_member->interface, cur_member->penalty,
-					ast_test_flag(cur_member, QUEUE_MEMBER_PAUSED) ? 1 : 0,
-					cur_member->membername, cur_member->device->state_interface,
-					ast_test_flag(cur_member, QUEUE_MEMBER_CALLINUSE) ? 1 : 0);
-
+			value_len ? "|" : "", cur_member->interface, cur_member->penalty,cur_member->paused,
+					cur_member->membername, cur_member->device->state_interface, cur_member->callinuse);
 		ao2_unlock(cur_member);
 		ao2_ref(cur_member, -1);
 
@@ -5799,13 +5776,13 @@
 	ao2_lock(mem);
 	/* XXX future changes should beware of this assumption!! */
 	/*Change Penalty on realtime users*/
-	if (ast_test_flag(mem, QUEUE_MEMBER_REALTIME) && negative_penalty_invalid) {
+	if (mem->realtime && negative_penalty_invalid) {
 		update_realtime_member_field(mem, q->name, "penalty", "-1");
-	} else if (!ast_test_flag(mem, QUEUE_MEMBER_DYNAMIC)) {
+	} else if (!mem->dynamic) {
 		ao2_unlock(mem);
 		ao2_ref(mem, -1);
 		return RES_NOT_DYNAMIC;
-	} else if (ast_test_flag(mem, QUEUE_MEMBER_DYNAMIC)) {
+	} else if (mem->dynamic) {
 		reload = 1;
 	}
 	manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
@@ -5833,12 +5810,8 @@
 static int do_set_member_penalty_paused(struct call_queue *q, struct member *mem, int pause, int value, const char *reason)
 {
 	if (pause) {
-		if (value) {
-			ast_set_flag(mem, QUEUE_MEMBER_PAUSED);
-		} else {
-			ast_clear_flag(mem, QUEUE_MEMBER_PAUSED);
-		}
-		if (ast_test_flag(mem, QUEUE_MEMBER_REALTIME) &&
+		mem->paused = (value) ? 1 : 0;
+		if (mem->realtime &&
 		    update_realtime_member_field(mem, q->name, "paused", (value) ? "1" : "0")) {
 			ast_log(LOG_WARNING, "Failed %spausing realtime member %s queue %s\n",
 					(value) ? "" : "un", mem->membername, q->name);
@@ -5865,7 +5838,7 @@
 		}
 	} else {
 		mem->penalty = value;
-		if (ast_test_flag(mem, QUEUE_MEMBER_REALTIME)) {
+		if (mem->realtime) {
 			char *rtpenalty;
 			if (!asprintf(&rtpenalty,"%i", mem->penalty) ||
 			    update_realtime_member_field(mem, q->name, "penalty", rtpenalty)) {
@@ -5883,7 +5856,7 @@
 			q->name, mem->interface, mem->penalty);
 	}
 
-	if (ast_test_flag(mem, QUEUE_MEMBER_DYNAMIC) && queue_persistent_members) {
+	if (mem->dynamic && queue_persistent_members) {
 		dump_queue_members(q);
 	}
 
@@ -5906,11 +5879,9 @@
 			ao2_ref(q, -1);
 			return RESULT_FAILURE;
 		}
-		ao2_lock(q->data->members);
 		ao2_lock(mem);
 		found = !do_set_member_penalty_paused(q, mem, 1, paused, reason);
 		ao2_unlock(mem);
-		ao2_unlock(q->data->members);
 		ao2_ref(mem, -1);
 		ao2_ref(q, -1);
 		return (!found) ? RESULT_FAILURE : RESULT_SUCCESS;
@@ -5925,13 +5896,11 @@
 	queue_iter = ao2_iterator_init(queues, 0);
 	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate over queues"))) {
 		if ((mem = interface_exists(q, interface))) {
-			ao2_lock(q->data->members);
 			ao2_lock(mem);
 			if (!do_set_member_penalty_paused(q, mem, 1, paused, reason)) {
 				found ++;
 			}
 			ao2_unlock(mem);
-			ao2_unlock(q->data->members);
 			ao2_ref(mem, -1);
 		}
 		ao2_t_ref(q, -1, "Done with iterator");
@@ -6334,7 +6303,7 @@
 	);
 	/* Our queue entry */
 	struct queue_ent qe = { 0 };
-	
+
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule[,position]]]]]]]]]\n");
 		return -1;
@@ -6429,7 +6398,7 @@
 	qe.min_penalty = min_penalty;
 	qe.last_pos_said = 0;
 	qe.last_pos = ast_tv(0, 0);
-	qe.last_periodic_announce_time = ast_tvnow();
+	qe.last_pannounce_time = ast_tvnow();
 	qe.last_periodic_announce_sound = 0;
 	qe.valid_digits = 0;
 
@@ -6731,7 +6700,7 @@
 				ao2_lock(m);
 				/* Count the agents who are logged in and presently answering calls */
 				status = get_device_status(m);
-				if ((status == AST_DEVICE_NOT_INUSE) && (!ast_test_flag(m, QUEUE_MEMBER_PAUSED))) {
+				if ((status == AST_DEVICE_NOT_INUSE) && (!m->paused)) {
 					count++;
 				}
 				ao2_unlock(m);
@@ -6744,7 +6713,7 @@
 				ao2_lock(m);
 				/* Count the agents who are logged in, not paused and not wrapping up */
 				status = get_device_status(m);
-				if ((status == AST_DEVICE_NOT_INUSE) && (!ast_test_flag(m, QUEUE_MEMBER_PAUSED)) &&
+				if ((status == AST_DEVICE_NOT_INUSE) && !m->paused &&
 				    !(!ast_tvzero(m->lastcall) && m->lastwrapup &&
 				      (ast_tvdiff_sec(ast_tvnow(), m->lastcall) <= m->lastwrapup))) {
 					count++;
@@ -6764,13 +6733,13 @@
 		} else if (!strcasecmp(args.option, "paused") && !ast_strlen_zero(args.interface) &&
 			   ((m = interface_exists(q, args.interface)))) {
 			ao2_lock(m);
-			count = ast_test_flag(m, QUEUE_MEMBER_PAUSED) ? 1 : 0;
+			count = m->paused;
 			ao2_unlock(m);
 			ao2_ref(m, -1);
 		} else if (!strcasecmp(args.option, "callinuse") && !ast_strlen_zero(args.interface) &&
 			   ((m = interface_exists(q, args.interface)))) {
 			ao2_lock(m);
-			count = ast_test_flag(m, QUEUE_MEMBER_CALLINUSE) ? 1 : 0;
+			count = m->callinuse;
 			ao2_unlock(m);
 			ao2_ref(m, -1);
 		}
@@ -6844,17 +6813,11 @@
 			return -1;
 		}
 		if (!strcasecmp(args.option, "callinuse")) {
-			ao2_lock(q->data->members);
 			ao2_lock(m);
-			if (memvalue) {
-				ast_set_flag(m, QUEUE_MEMBER_CALLINUSE);
-			} else {
-				ast_clear_flag(m, QUEUE_MEMBER_CALLINUSE);
-			}
-			ao2_unlock(q->data->members);
-			if (ast_test_flag(m, QUEUE_MEMBER_REALTIME)) {
+			m->callinuse = (memvalue) ? 1 : 0;
+			if (m->realtime) {
 				update_realtime_member_field(m, q->name, args.option, value);
-			} else if (ast_test_flag(m, QUEUE_MEMBER_DYNAMIC)) {
+			} else if (m->dynamic) {
 				reload = 1;
 			}
 			ao2_unlock(m);
@@ -7274,10 +7237,8 @@
 {
 	struct member *member = obj;
 
-	if (!ast_test_flag(member, QUEUE_MEMBER_DYNAMIC) && !ast_test_flag(member, QUEUE_MEMBER_REALTIME)) {
-		ao2_lock(member);
-		ast_set_flag(member, QUEUE_MEMBER_DEAD);
-		ao2_unlock(member);
+	if (!member->dynamic && !member->realtime) {
+		member->dead = 1;
 		return CMP_MATCH;
 	}
 
@@ -7291,8 +7252,7 @@
 {
 	struct member *member = obj;
 
-	if ((!ast_test_flag(member, QUEUE_MEMBER_DYNAMIC) && !ast_test_flag(member, QUEUE_MEMBER_REALTIME)) &&
-	    ast_test_flag(member, QUEUE_MEMBER_DEAD)) {
+	if (!member->dynamic && !member->realtime && member->dead) {
 		return CMP_MATCH;
 	}
 	return 0;
@@ -7690,9 +7650,9 @@
 				}
 				status = get_device_status(mem);
 				ast_str_append(&out, 0, "%s%s%s (%s)",
-					ast_test_flag(mem, QUEUE_MEMBER_DYNAMIC) ? " (dynamic)" : "",
-					ast_test_flag(mem, QUEUE_MEMBER_REALTIME) ? " (realtime)" : "",
-					ast_test_flag(mem, QUEUE_MEMBER_PAUSED) ? " (paused)" : "",
+					mem->dynamic ? " (dynamic)" : "",
+					mem->realtime ? " (realtime)" : "",
+					mem->paused ? " (paused)" : "",
 					ast_devstate2str(status));
 
 				if (mem->calls) {
@@ -7889,8 +7849,8 @@

[... 101 lines stripped ...]



More information about the svn-commits mailing list