Index: apps/app_queue.c
===================================================================
--- apps/app_queue.c	(revision 7373)
+++ apps/app_queue.c	(working copy)
@@ -758,8 +758,7 @@
 
 /*!\brief Reload a single queue via realtime.
    \return Return the queue, or NULL if it doesn't exist.
-   \note Should be called with the global qlock locked.
-   When found, the queue is returned with q->lock locked. */
+   \note Should be called with the global qlock locked. */
 static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
 {
 	struct ast_variable *v;
@@ -788,6 +787,7 @@
 				ast_mutex_unlock(&q->lock);
 				return NULL;
 			} else {
+				ast_mutex_unlock(&q->lock);
 				return q;
 			}
 		}
@@ -882,50 +882,74 @@
 		m = next_m;
 	}
 
+	ast_mutex_unlock(&q->lock);
+
 	return q;
 }
 
-static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
+static struct ast_call_queue *load_realtime_queue(char *queuename)
 {
 	struct ast_variable *queue_vars = NULL;
 	struct ast_config *member_config = NULL;
 	struct ast_call_queue *q;
+
+	/* Find the queue in the in-core list first. */
+	q = queues;
+	while (q) {
+		if (!strcasecmp(q->name, queuename)) {
+			break;
+		}
+		q = q->next;
+	}
+
+	if (!q) {
+		/*! \note Load from realtime before taking the global qlock, to avoid blocking all
+		   queue operations while waiting for the DB.
+
+		   This will be two separate database transactions, so we might
+		   see queue parameters as they were before another process
+		   changed the queue and member list as it was after the change.
+		   Thus we might see an empty member list when a queue is
+		   deleted. In practise, this is unlikely to cause a problem. */
+		queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
+		if (queue_vars) {
+			member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
+			if (!member_config) {
+				ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
+				return NULL;
+			}
+		}
+
+		ast_mutex_lock(&qlock);
+
+		q = find_queue_by_name_rt(queuename, queue_vars, member_config);
+		if(member_config)
+			ast_config_destroy(member_config);
+		if(queue_vars)
+			ast_variables_destroy(queue_vars);
+
+		ast_mutex_unlock(&qlock);
+	}
+
+	return q;
+}
+
+static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
+{
+	struct ast_call_queue *q;
 	struct queue_ent *cur, *prev = NULL;
 	int res = -1;
 	int pos = 0;
 	int inserted = 0;
 	enum queue_member_status stat;
 
-	/*! \note Load from realtime before taking the global qlock, to avoid blocking all
-	   queue operations while waiting for the DB.
+	q = load_realtime_queue(queuename);
+	if (!q)
+		return res;
 
-	   This will be two separate database transactions, so we might
-	   see queue parameters as they were before another process
-	   changed the queue and member list as it was after the change.
-	   Thus we might see an empty member list when a queue is
-	   deleted. In practise, this is unlikely to cause a problem. */
-	queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
-	if (queue_vars) {
-		member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
-		if (!member_config) {
-			ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
-			return res;
-		}
-	}
-
 	ast_mutex_lock(&qlock);
-	q = find_queue_by_name_rt(queuename, queue_vars, member_config);
-	/* Note: If found, find_queue_by_name_rt() returns with q->lock locked. */
-	if(member_config)
-		ast_config_destroy(member_config);
-	if(queue_vars)
-		ast_variables_destroy(queue_vars);
+	ast_mutex_lock(&q->lock);
 
-	if (!q) {
-		ast_mutex_unlock(&qlock);
-		return res;
-	}
-
 	/* This is our one */
 	stat = get_member_status(q);
 	if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
@@ -2404,7 +2428,10 @@
 	struct member *new_member;
 	int res = RES_NOSUCHQUEUE;
 
+	q = load_realtime_queue(queuename);
+
 	ast_mutex_lock(&qlock);
+
 	for (q = queues ; q ; q = q->next) {
 		ast_mutex_lock(&q->lock);
 		if (!strcmp(q->name, queuename)) {
@@ -3272,7 +3300,13 @@
 	time(&now);
 	if ((!queue_show && argc != 2) || (queue_show && argc != 3))
 		return RESULT_SHOWUSAGE;
+
+	/* We only want to load realtime queues when a specific queue is asked for. */
+	if (queue_show)
+		q = load_realtime_queue(argv[2]);
+
 	ast_mutex_lock(&qlock);
+
 	q = queues;
 	if (!q) {	
 		ast_mutex_unlock(&qlock);
