Bug 5936 - Cannot AddQueueMember on realtime queue, if queue not yet loaded (different fix than 1.2)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@8402 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Tilghman Lesher 20 years ago
parent e040a10d81
commit 41c87ccb97

@ -791,8 +791,7 @@ static void rt_handle_member_record(struct ast_call_queue *q, char *interface, c
/*!\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;
@ -818,6 +817,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
ast_mutex_unlock(&q->lock);
return NULL;
} else {
ast_mutex_unlock(&q->lock);
return q;
}
}
@ -911,20 +911,27 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
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;
struct queue_ent *cur, *prev = NULL;
int res = -1;
int pos = 0;
int inserted = 0;
enum queue_member_status stat;
/* Find the queue in the in-core list first. */
ast_mutex_lock(&qlock);
for (q = queues; q; q = q->next) {
if (!strcasecmp(q->name, queuename)) {
break;
}
}
ast_mutex_unlock(&qlock);
if (!q) {
/*! \note Load from realtime before taking the global qlock, to avoid blocking all
queue operations while waiting for the DB.
@ -933,28 +940,45 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
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;
return NULL;
}
}
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);
if (!q) {
ast_mutex_unlock(&qlock);
return res;
}
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;
q = load_realtime_queue(queuename);
if (!q)
return res;
ast_mutex_lock(&qlock);
ast_mutex_lock(&q->lock);
/* This is our one */
stat = get_member_status(q, qe->max_penalty);
if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
@ -2452,10 +2476,14 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
struct member *new_member;
int res = RES_NOSUCHQUEUE;
/* \note Ensure the appropriate realtime queue is loaded. Note that this
* short-circuits if the queue is already in memory. */
q = load_realtime_queue(queuename);
ast_mutex_lock(&qlock);
for (q = queues ; q ; q = q->next) {
if (q) {
ast_mutex_lock(&q->lock);
if (!strcmp(q->name, queuename)) {
if (interface_exists(q, interface) == NULL) {
new_member = create_queue_member(interface, penalty, paused);
@ -2486,9 +2514,6 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
res = RES_EXISTS;
}
ast_mutex_unlock(&q->lock);
break;
}
ast_mutex_unlock(&q->lock);
}
ast_mutex_unlock(&qlock);
return res;
@ -3411,7 +3436,13 @@ static int __queues_show(int manager, int fd, int argc, char **argv, int queue_s
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)
load_realtime_queue(argv[2]);
ast_mutex_lock(&qlock);
q = queues;
if (!q) {
ast_mutex_unlock(&qlock);

Loading…
Cancel
Save