[svn-commits] irroot: branch irroot/asterisk-trunk-quack-queue r343850 - /team/irroot/aster...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Nov 8 10:00:59 CST 2011
Author: irroot
Date: Tue Nov 8 10:00:55 2011
New Revision: 343850
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=343850
Log:
Log member remove on exit allow reload time for call_queue
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=343850&r1=343849&r2=343850
==============================================================================
--- team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c (original)
+++ team/irroot/asterisk-trunk-quack-queue/apps/app_queue.c Tue Nov 8 10:00:55 2011
@@ -905,6 +905,7 @@
QUEUE_RELOAD_MEMBER = (1 << 1),
QUEUE_RELOAD_RULES = (1 << 2),
QUEUE_RESET_STATS = (1 << 3),
+ QUEUE_RELOAD_REALTIME = (1 << 4),
};
static const struct strategy {
@@ -1206,17 +1207,16 @@
int maxlen; /*!< Max number of entries */
int wrapuptime; /*!< Wrapup Time */
int penaltymemberslimit; /*!< Disregard penalty when queue has fewer than this many members */
-
int retry; /*!< Retry calling everyone after this amount of time */
int timeout; /*!< How long to wait for an answer */
int weight; /*!< Respective weight */
int autopause; /*!< Auto pause queue members if they fail to answer */
int autopausedelay; /*!< Delay auto pause for autopausedelay seconds since last call */
int timeoutpriority; /*!< Do we allow a fraction of the timeout to occur for a ring? */
-
/* Queue strategy things */
int memberdelay; /*!< Seconds to delay connecting member to caller */
int autofill; /*!< Ignore the head call status and ring an available agent */
+ struct timeval reload; /*!< Time the queue will be reloaded from RT */
struct queue_data *data; /*!< Queue statistics */
};
@@ -1735,36 +1735,14 @@
}
/*!
- * \brief helper function used in creating the hash
- */
-static int compress_char(const char c)
-{
- if (c < 32) {
- return 0;
- } else if (c > 96) {
- return c - 64;
- } else {
- return c - 32;
- }
-}
-
-/*!
* \brief ao2 callback to calculate hash of a member by interface
*/
static int member_hash_fn(const void *obj, const int flags)
{
const struct member *mem = obj;
const char *interface = (flags & OBJ_KEY) ? obj : mem->interface;
- const char *chname = strchr(interface, '/');
- int ret = 0, i;
-
- if (!chname) {
- chname = interface;
- }
- for (i = 0; i < 5 && chname[i]; i++) {
- ret += compress_char(chname[i]) << (i * 6);
- }
- return ret;
+
+ return ast_str_case_hash(interface);
}
/*!
@@ -1838,6 +1816,7 @@
ao2_lock(mem);
mem->calls = 0;
+ mem->lastwrapup = 0;
mem->lastcall = ast_tv(0, 0);
ao2_unlock(mem);
@@ -1930,16 +1909,8 @@
const struct callattempt *c = obj;
const struct member *mem = c->member;
const char *interface = (flags & OBJ_KEY) ? obj : mem->interface;
- const char *chname = strchr(interface, '/');
- int ret = 0, i;
-
- if (!chname) {
- chname = interface;
- }
- for (i = 0; i < 5 && chname[i]; i++) {
- ret += compress_char(chname[i]) << (i * 6);
- }
- return ret;
+
+ return ast_str_case_hash(interface);
}
@@ -2031,6 +2002,9 @@
if (q->sound_periodicannounce[i])
ast_str_set(&q->sound_periodicannounce[i], 0, "%s", "");
}
+
+ q->reload = ast_tvnow();
+ q->reload.tv_sec += 86400;
}
/*!
@@ -2053,7 +2027,7 @@
}
contentdup = ast_strdupa(content);
-
+
if (!(maxstr = strchr(contentdup, ','))) {
ast_log(LOG_WARNING, "Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
ao2_ref(rule, -1);
@@ -2489,8 +2463,10 @@
} else if ((rt_m = ao2_callback(q->data->members, 0, member_cmp_uniqueid_fn, rt_uniqueid))) {
/*make sure there no duplicates this should never happen am i changing interface perhaps ??*/
dead = 1;
+ ao2_lock(rt_m);
ast_log(AST_LOG_WARNING, "Duplicate uniqueid found while adding %s (%s) found %s (%s) on queue %s : Not adding\n",
m->interface, m->membername, rt_m->interface, rt_m->membername, q->name);
+ ao2_unlock(rt_m);
ao2_ref(rt_m, -1);
} else {
ast_string_field_set(m, rt_uniqueid, rt_uniqueid);
@@ -2622,7 +2598,6 @@
free(q->sound_periodicannounce[i]);
}
ao2_ref(q->data, -1);
- ast_log(AST_LOG_WARNING, "Releasing Queue %s\n", q->name);
}
/*! \brief create a new call_queue structure */
@@ -2631,18 +2606,15 @@
struct call_queue *q;
if (!(q = ao2_t_alloc(sizeof(*q), destroy_queue, "Allocate queue"))) {
- ast_log(AST_LOG_ERROR, "Memory allocation error\n");
return NULL;
}
-
+
if (!(q->data = get_queue_data(queuename))) {
- ast_log(AST_LOG_ERROR, "Memory allocation error\n");
ao2_ref(q, -1);
return NULL;
}
if (ast_string_field_init(q, 64)) {
- ast_log(AST_LOG_ERROR, "Memory allocation error\n");
ao2_ref(q->data, -1);
ao2_ref(q, -1);
return NULL;
@@ -2665,7 +2637,7 @@
* \retval the queue,
* \retval NULL if it doesn't exist.
*/
-static struct call_queue *load_realtime_queue(const char *queuename, int rmask)
+static struct call_queue *load_realtime_queue(const char *queuename, struct ast_flags *mask)
{
struct ast_variable *v;
const char *tmp_name;
@@ -2675,12 +2647,20 @@
struct ast_variable *queue_vars;
struct call_queue *q, *oldq;
int found;
+ int reload_queue = (mask) ? ast_test_flag(mask, QUEUE_RELOAD_PARAMETERS) : 0;
+ int reload_members = (mask) ? ast_test_flag(mask, QUEUE_RELOAD_MEMBER) : 0;
+ int reload_realtime = (mask) ? ast_test_flag(mask, QUEUE_RELOAD_REALTIME) : 0;
if ((q = ao2_t_find(queues, queuename, OBJ_KEY, "Look for queue in memory first")) &&
- (!q->realtime || !(rmask & QUEUE_RELOAD_PARAMETERS))) {
- if (rmask & QUEUE_RELOAD_MEMBER) {
+ (!q->realtime || !reload_queue)) {
+ if (reload_members) {
rt_load_member_config(q);
}
+ return q;
+ }
+
+ if (!reload_realtime && !ast_tvzero(q->reload) && ast_tvdiff_sec(ast_tvnow(), q->reload)) {
+ ast_log(AST_LOG_WARNING, "Not reloading queue for next %ld Seconds\n", (long)ast_tvdiff_sec(q->reload, ast_tvnow()));
return q;
}
@@ -2717,7 +2697,6 @@
ast_variables_destroy(queue_vars);
return NULL;
}
- ast_log(AST_LOG_WARNING, "Reconfiguring Queue\n");
}
init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
@@ -2763,7 +2742,7 @@
}
/* Load realtime members*/
- if (rmask & QUEUE_RELOAD_MEMBER) {
+ if (reload_members) {
rt_load_member_config(q);
}
@@ -2794,7 +2773,8 @@
return ret;
}
-static void load_all_realtime_queues(int rmask) {
+static void load_all_realtime_queues(struct ast_flags *mask)
+{
char *queuename;
struct ast_config *cfg;
struct call_queue *queue;
@@ -2804,7 +2784,7 @@
for (queuename = ast_category_browse(cfg, NULL);
!ast_strlen_zero(queuename);
queuename = ast_category_browse(cfg, queuename)) {
- if ((queue = load_realtime_queue(queuename, rmask))) {
+ if ((queue = load_realtime_queue(queuename, mask))) {
ao2_ref(queue, -1);
}
}
@@ -2819,8 +2799,9 @@
int res = -1;
int pos = 0;
int inserted = 0;
-
- if (!(q = load_realtime_queue(queuename, QUEUE_RELOAD_PARAMETERS))) {
+ struct ast_flags qflags = {QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER};
+
+ if (!(q = load_realtime_queue(queuename, &qflags))) {
return res;
}
@@ -2832,7 +2813,7 @@
ao2_t_ref(q, -1, "Done with realtime queue");
return res;
}
-
+
ao2_lock(q->data);
if ((*reason == QUEUE_UNKNOWN && q->maxlen && (q->data->count >= q->maxlen)) ||
(*reason != QUEUE_UNKNOWN)) {
@@ -3612,10 +3593,11 @@
static int ring_one(struct queue_ent *qe, int *busies)
{
int ret = 0;
- struct callattempt *cur, *best = NULL;
+ struct callattempt *cur, *best;
struct ao2_iterator aiter;
while (ret == 0) {
+ best = NULL;
ao2_callback_data(qe->attempts, OBJ_NODATA | OBJ_MULTIPLE, get_best_metric_cb, NULL, &best);
if (!best) {
ast_debug(1, "Nobody left to try ringing in queue\n");
@@ -3746,10 +3728,11 @@
/* Resume Music on Hold if the caller is going to stay in the queue */
if (!res) {
- if (ringing)
+ if (ringing) {
ast_indicate(qe->chan, AST_CONTROL_RINGING);
- else
+ } else {
ast_moh_start(qe->chan, qe->parent->moh, NULL);
+ }
}
/* update last_periodic_announce_time */
@@ -3763,7 +3746,7 @@
if (!qe->parent->randomperiodicannounce) {
qe->last_periodic_announce_sound++;
}
-
+
return res;
}
@@ -3826,12 +3809,14 @@
}
}
if (qe->parent->autopause == QUEUE_AUTOPAUSE_ON) {
- if (!set_member_paused(qe->parent->name, call->member->interface, "Auto-Pause", 1)) {
+ 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",
call->member->interface, qe->parent->name);
} else {
ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", call->member->interface, qe->parent->name);
}
+ ao2_unlock(call->member);
} else {
/* If queue autopause is mode all, just don't send any queue to stop.
* the function will stop in all queues */
@@ -4358,7 +4343,7 @@
{
int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
- char max_penalty_str[20], min_penalty_str[20];
+ char max_penalty_str[20], min_penalty_str[20];
int next = qe->pr->time;
/* a relative change to the penalty could put it below 0 */
@@ -4429,7 +4414,7 @@
if (qe->parent->periodicannouncefrequency &&
(res = say_periodic_announcement(qe,ringing)))
break;
-
+
/* see if we need to move to the next penalty level for this queue */
while (qe->pr && (ast_tvdiff_sec(ast_tvnow(), qe->start) >= qe->pr->time)) {
update_qe_rule(qe);
@@ -4440,15 +4425,16 @@
*reason = QUEUE_TIMEOUT;
break;
}
-
+
/* Wait a second before checking again */
if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
- if (res > 0 && !valid_exit(qe, res))
+ if (res > 0 && !valid_exit(qe, res)) {
res = 0;
- else
+ } else {
break;
- }
-
+ }
+ }
+
/* If we have timed out, break out */
if (!ast_tvzero(qe->expire) && (ast_tvcmp(ast_tvnow(), qe->expire) >= 0)) {
*reason = QUEUE_TIMEOUT;
@@ -5050,8 +5036,7 @@
if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED) {
store_next_rr(qe);
- }
- if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
+ } else if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
store_next_lin(qe);
}
@@ -5090,10 +5075,12 @@
/* Ah ha! Someone answered within the desired timeframe. Of course after this
we will always return with -1 so that it is hung up properly after the
conversation. */
- if (!strcmp(qe->chan->tech->type, "DAHDI"))
+ if (!strcmp(qe->chan->tech->type, "DAHDI")) {
ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
- if (!strcmp(peer->tech->type, "DAHDI"))
+ }
+ if (!strcmp(peer->tech->type, "DAHDI")) {
ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
+ }
/* Update parameters for the queue */
now = ast_tvnow();
recalc_holdtime(qe, ast_tvdiff_sec(now, qe->start));
@@ -5468,7 +5455,7 @@
}
qe->handled++;
ao2_lock(member);
- ast_queue_log(qe->parent->name, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld",
+ 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);
@@ -5501,6 +5488,8 @@
ao2_unlock(member);
}
}
+
+ callstart = ast_tvnow();
ao2_lock(member);
if (qe->parent->eventwhencalled)
@@ -5515,7 +5504,7 @@
"Ringtime: %ld\r\n"
"%s",
qe->parent->name, qe->chan->uniqueid, peer->name, member->interface, member->membername,
- (long)ast_tvdiff_sec(ast_tvnow(), qe->start), peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
+ (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)) : "");
ao2_unlock(member);
@@ -5535,7 +5524,6 @@
ao2_t_ref(qe->parent, 1, "For bridge_config reference");
}
- callstart = ast_tvnow();
transfer_ds = setup_transfer_datastore(qe, member, callstart, callcompletedinsl);
bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
@@ -5689,7 +5677,7 @@
struct member *mem;
int reload = 0;
- if (!(q = load_realtime_queue(queuename, 0))) {
+ if (!(q = load_realtime_queue(queuename, NULL))) {
return RES_NOSUCHQUEUE;
}
if (!(mem = interface_exists(q, interface))) {
@@ -5800,7 +5788,7 @@
struct ao2_iterator queue_iter;
if (!ast_strlen_zero(queuename)) {
- if (!(q = load_realtime_queue(queuename, 0))) {
+ if (!(q = load_realtime_queue(queuename, NULL))) {
return RESULT_FAILURE;
}
if (!(mem = interface_exists(q, interface))) {
@@ -5816,7 +5804,7 @@
return (!found) ? RESULT_FAILURE : RESULT_SUCCESS;
}
- load_all_realtime_queues(0);
+ load_all_realtime_queues(NULL);
/* Special event for when all queues are paused - individual events still generated */
/* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
@@ -5853,7 +5841,7 @@
}
if (!ast_strlen_zero(queuename)) {
- if (!(q = load_realtime_queue(queuename, 0))) {
+ if (!(q = load_realtime_queue(queuename, NULL))) {
return RESULT_FAILURE;
}
if (!(mem = interface_exists(q, interface))) {
@@ -5869,7 +5857,7 @@
return RESULT_SUCCESS;
}
- load_all_realtime_queues(0);
+ load_all_realtime_queues(NULL);
queue_iter = ao2_iterator_init(queues, 0);
while ((q = ao2_t_iterator_next(&queue_iter, "Iterate over queues"))) {
@@ -6115,7 +6103,7 @@
ast_category_append(mcfg, mcat);
}
- if (!(q = load_realtime_queue(args.queuename, 0))) {
+ if (!(q = load_realtime_queue(args.queuename, NULL))) {
ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", args.queuename);
pbx_builtin_setvar_helper(chan, "AQMSTATUS", "NOSUCHQUEUE");
return 0;
@@ -6237,7 +6225,7 @@
ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule[,position]]]]]]]]]\n");
return -1;
}
-
+
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
@@ -6363,8 +6351,8 @@
record_abandoned(&qe);
reason = QUEUE_TIMEOUT;
res = 0;
- ast_queue_log(args.queuename, chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld",
- qe.pos, qe.opos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
+ ast_queue_log(args.queuename, chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d||%ld",
+ qe.pos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
break;
}
@@ -6386,7 +6374,8 @@
record_abandoned(&qe);
reason = QUEUE_TIMEOUT;
res = 0;
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
+ ast_queue_log(args.queuename, chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld",
+ qe.pos, qe.opos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
break;
}
@@ -6415,20 +6404,21 @@
/* exit after 'timeout' cycle if 'n' option enabled */
if (noption && tries >= ao2_container_count(qe.parent->data->members)) {
ast_verb(3, "Exiting on time-out cycle\n");
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
+ ast_queue_log(args.queuename, chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld",
+ qe.pos, qe.opos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
record_abandoned(&qe);
reason = QUEUE_TIMEOUT;
res = 0;
break;
}
-
/* Leave if we have exceeded our queuetimeout */
if (!ast_tvzero(qe.expire) && (ast_tvcmp(ast_tvnow(), qe.expire) >= 0)) {
record_abandoned(&qe);
reason = QUEUE_TIMEOUT;
res = 0;
- ast_queue_log(qe.parent->name, qe.chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld", qe.pos, qe.opos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
+ ast_queue_log(args.queuename, chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld",
+ qe.pos, qe.opos, (long)ast_tvdiff_sec(ast_tvnow(), qe.start));
break;
}
@@ -6523,7 +6513,7 @@
return -1;
}
- if ((q = load_realtime_queue(data, 0))) {
+ if ((q = load_realtime_queue(data, NULL))) {
if (q->setqueuevar) {
sl = 0;
res = 0;
@@ -6564,7 +6554,7 @@
ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
return -1;
}
- q = load_realtime_queue(data, 0);
+ q = load_realtime_queue(data, NULL);
snprintf(buf, len, "%d", q != NULL? 1 : 0);
if (q) {
ao2_t_ref(q, -1, "Done with temporary reference in QUEUE_EXISTS()");
@@ -6602,7 +6592,7 @@
AST_STANDARD_APP_ARGS(args, data);
- if ((q = load_realtime_queue(args.queuename, QUEUE_RELOAD_MEMBER))) {
+ if ((q = load_realtime_queue(args.queuename, NULL))) {
if (!strcasecmp(args.option, "logged")) {
mem_iter = ao2_iterator_init(q->data->members, 0);
while ((m = ao2_iterator_next(&mem_iter))) {
@@ -6725,7 +6715,7 @@
return -1;
}
} else if (!ast_strlen_zero(args.queuename)) {
- if (!(q = load_realtime_queue(args.queuename, 0))) {
+ if (!(q = load_realtime_queue(args.queuename, NULL))) {
ast_log(LOG_ERROR, "Invalid queue %s\n", args.queuename);
return -1;
}
@@ -6784,7 +6774,7 @@
return -1;
}
- if ((q = load_realtime_queue(data, QUEUE_RELOAD_MEMBER))) {
+ if ((q = load_realtime_queue(data, NULL))) {
mem_iter = ao2_iterator_init(q->data->members, 0);
while ((m = ao2_iterator_next(&mem_iter))) {
ao2_lock(m);
@@ -6857,7 +6847,7 @@
return -1;
}
- if ((q = load_realtime_queue(data, QUEUE_RELOAD_MEMBER))) {
+ if ((q = load_realtime_queue(data, NULL))) {
ast_log(LOG_WARNING, "queue %s was not found\n", data);
return -1;
}
@@ -6912,7 +6902,7 @@
return -1;
}
- if (!(q = load_realtime_queue(args.queuename, 0))) {
+ if (!(q = load_realtime_queue(args.queuename, NULL))) {
ast_log(AST_LOG_WARNING, "Queue %s does not exist\n", args.queuename);
return -1;
}
@@ -7203,6 +7193,7 @@
struct ast_category *mcat;
const char *interface = NULL;
+
if (!(q = ao2_t_find(queues, queuename, OBJ_KEY, "Find queue for reload"))) {
/* Make one then */
if (!queue_reload || (!(q = alloc_queue(queuename, 0)))) {
@@ -7307,6 +7298,35 @@
}
return 0;
+}
+
+/*!
+ * \brief ao2 callback to delete realtime members marked dead
+ */
+static int remove_all_members_from_queue(void *obj, void *arg, void *data, int flags)
+{
+ struct member *m = obj;
+ const struct call_queue *q = data;
+
+ ao2_lock(m);
+ if (ast_strlen_zero(m->membername) || !log_membername_as_agent) {
+ ast_queue_log(q->name, "SHUTDOWN", m->interface, "REMOVEMEMBER", "%s", "");
+ } else {
+ ast_queue_log(q->name, "SHUTDOWN", m->membername, "REMOVEMEMBER", "%s", "");
+ }
+ ao2_unlock(m);
+ return CMP_MATCH;
+}
+
+/*!
+ * \brief ao2 callback to delete realtime members marked dead
+ */
+static int remove_all_members(void *obj, void *arg, int flags)
+{
+ struct call_queue *q = obj;
+
+ ao2_callback_data(q->data->members, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, remove_all_members_from_queue, NULL, q);
+ return CMP_MATCH;
}
/*! \brief reload the queues.conf file
@@ -7327,40 +7347,53 @@
char *cat;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
const int queue_reload = ast_test_flag(mask, QUEUE_RELOAD_PARAMETERS);
+ const int reload_members = ast_test_flag(mask, QUEUE_RELOAD_MEMBER);
+ struct call_queue *q;
+ int loaded = 0;
if (!(cfg = ast_config_load("queues.conf", config_flags))) {
ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
return -1;
- } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
- return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Config file queues.conf is in an invalid format. Aborting.\n");
return -1;
}
- /* Mark all queues as dead for the moment if we're reloading queues.
- * For clarity, we could just be reloading members, in which case we don't want to mess
- * with the other queue parameters at all*/
- if (queue_reload) {
- ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE, mark_queues_dead, (char *) queuename);
- }
-
- /* Chug through config file */
- cat = NULL;
- while ((cat = ast_category_browse(cfg, cat)) ) {
- if (!strcasecmp(cat, "general") && queue_reload) {
- queue_set_global_params(cfg);
- continue;
- }
- if (ast_strlen_zero(queuename) || !strcasecmp(cat, queuename)) {
- reload_single_queue(cfg, mask, cat);
- }
- }
-
- ast_config_destroy(cfg);
- /* Unref all the dead queues if we were reloading queues */
- if (queue_reload) {
- ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, kill_dead_queues, (char *) queuename);
+ if (cfg != CONFIG_STATUS_FILEUNCHANGED) {
+ /* Mark all queues as dead for the moment if we're reloading queues.
+ * For clarity, we could just be reloading members, in which case we don't want to mess
+ * with the other queue parameters at all*/
+ if (queue_reload) {
+ ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE, mark_queues_dead, (char *) queuename);
+ }
+
+ /* Chug through config file */
+ cat = NULL;
+ while ((cat = ast_category_browse(cfg, cat)) ) {
+ if (!strcasecmp(cat, "general") && queue_reload) {
+ queue_set_global_params(cfg);
+ continue;
+ }
+ if (ast_strlen_zero(queuename) || !strcasecmp(cat, queuename)) {
+ loaded = 1;
+ reload_single_queue(cfg, mask, cat);
+ }
+ }
+
+ ast_config_destroy(cfg);
+ /* Unref all the dead queues if we were reloading queues */
+ if (queue_reload) {
+ ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, kill_dead_queues, (char *) queuename);
+ }
+ }
+
+ /* reload realtime queues*/
+ ast_set_flag(mask, QUEUE_RELOAD_REALTIME);
+ if (ast_strlen_zero(queuename)) {
+ load_all_realtime_queues(mask);
+ } else if ((!loaded || reload_members) &&
+ (q = load_realtime_queue(queuename, mask))) {
+ ao2_ref(q, -1);
}
return 0;
}
@@ -7459,10 +7492,10 @@
}
if ((argc == 3) &&
- (q = load_realtime_queue(argv[2], QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER))) {
+ (q = load_realtime_queue(argv[2], NULL))) {
ao2_ref(q, -1);
} else {
- load_all_realtime_queues(QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER);
+ load_all_realtime_queues(NULL);
}
queue_iter = ao2_iterator_init(queues, 0);
@@ -7685,8 +7718,8 @@
/* load realtime queue[s] */
if (ast_strlen_zero(queuefilter)) {
- load_all_realtime_queues(QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER);
- } else if ((q = load_realtime_queue(queuefilter, QUEUE_RELOAD_MEMBER | QUEUE_RELOAD_PARAMETERS))) {
+ load_all_realtime_queues(NULL);
+ } else if ((q = load_realtime_queue(queuefilter, NULL))) {
ao2_ref(q, -1);
}
@@ -7776,8 +7809,8 @@
/* load realtime queue[s] */
if (ast_strlen_zero(queuefilter)) {
- load_all_realtime_queues(QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER);
- } else if ((q = load_realtime_queue(queuefilter, QUEUE_RELOAD_PARAMETERS | QUEUE_RELOAD_MEMBER))) {
+ load_all_realtime_queues(NULL);
+ } else if ((q = load_realtime_queue(queuefilter, NULL))) {
ao2_ref(q, -1);
}
@@ -7898,7 +7931,7 @@
ast_category_append(mcfg, mcat);
}
- if (!(q = load_realtime_queue(queuename, 0))) {
+ if (!(q = load_realtime_queue(queuename, NULL))) {
astman_send_error(s, m, "Unable to add interface to queue: No such queue");
return 0;
}
@@ -7982,7 +8015,7 @@
return 0;
}
- if (!(q = load_realtime_queue(queuename, 0))) {
+ if (!(q = load_realtime_queue(queuename, NULL))) {
astman_send_error(s, m, "Invalid 'Queue'");
return 0;
}
@@ -8217,7 +8250,7 @@
ast_category_append(mcfg, mcat);
}
- if (!(q = load_realtime_queue(a->argv[5], 0))) {
+ if (!(q = load_realtime_queue(a->argv[5], NULL))) {
ast_cli(a->fd, "Unable to add interface to queue '%s': No such queue\n", a->argv[5]);
return CLI_FAILURE;
}
@@ -8466,7 +8499,7 @@
return CLI_SHOWUSAGE;
}
- if (!(q = load_realtime_queue(a->argv[7], 0))) {
+ if (!(q = load_realtime_queue(a->argv[7], NULL))) {
return CLI_FAILURE;
}
if ((m = interface_exists(q, a->argv[5]))) {
@@ -8955,7 +8988,7 @@
struct call_queue *queue;
/* load all queues from realtime*/
- load_all_realtime_queues(QUEUE_RELOAD_MEMBER | QUEUE_RELOAD_PARAMETERS);
+ load_all_realtime_queues(NULL);
/* static queues. */
i = ao2_iterator_init(queues, 0);
@@ -9019,7 +9052,7 @@
ast_context_destroy(con, "app_queue"); /* leave no trace */
}
- ao2_callback(queues, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
+ ao2_callback(queues, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, remove_all_members, NULL);
ao2_ref(queues, -1);
ao2_callback(qdata, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
More information about the svn-commits
mailing list