return q;
}
-/*! \note Returns a reference to the loaded realtime queue. */
-static struct call_queue *load_realtime_queue(const char *queuename)
+/*!
+ * note */
+
+/*!
+ * \internal
+ * \brief Returns reference to the named queue. If the queue is realtime, it will load the queue as well.
+ * \param queuename - name of the desired queue
+ *
+ * \retval the queue
+ * \retval NULL if it doesn't exist
+ */
+static struct call_queue *find_load_queue_rt_friendly(const char *queuename)
{
struct ast_variable *queue_vars;
struct ast_config *member_config = NULL;
int pos = 0;
int inserted = 0;
- if (!(q = load_realtime_queue(queuename))) {
+ if (!(q = find_load_queue_rt_friendly(queuename))) {
return res;
}
ao2_lock(q);
/*! \note Ensure the appropriate realtime queue is loaded. Note that this
* short-circuits if the queue is already in memory. */
- if (!(q = load_realtime_queue(queuename))) {
+ if (!(q = find_load_queue_rt_friendly(queuename))) {
return res;
}
return found ? RESULT_SUCCESS : RESULT_FAILURE;
}
-/* \brief Sets members penalty, if queuename=NULL we set member penalty in all the queues. */
+/*!
+ * \internal
+ * \brief helper function for set_member_penalty - given a queue, sets all member penalties with the interface
+ * \param[in] q queue which is having its member's penalty changed - must be unlocked prior to calling
+ * \param[in] interface String of interface used to search for queue members being changed
+ * \param[in] penalty Value penalty is being changed to for the member.
+ * \retval 0 if the there is no member with interface belonging to q and no change is made
+ * \retval 1 if the there is a member with interface belonging to q and changes are made
+ */
+static int set_member_penalty_help_members(struct call_queue *q, const char *interface, int penalty)
+{
+ struct member *mem;
+ int foundinterface = 0;
+ char rtpenalty[80];
+
+ ao2_lock(q);
+ if ((mem = interface_exists(q, interface))) {
+ foundinterface++;
+ if (!mem->realtime) {
+ mem->penalty = penalty;
+ } else {
+ sprintf(rtpenalty, "%i", penalty);
+ update_realtime_member_field(mem, q->name, "penalty", rtpenalty);
+ }
+ ast_queue_log(q->name, "NONE", interface, "PENALTY", "%d", penalty);
+ manager_event(EVENT_FLAG_AGENT, "QueueMemberPenalty",
+ "Queue: %s\r\n"
+ "Location: %s\r\n"
+ "Penalty: %d\r\n",
+ q->name, mem->interface, penalty);
+ ao2_ref(mem, -1);
+ }
+ ao2_unlock(q);
+
+ return foundinterface;
+}
+
+/*!
+ * \internal
+ * \brief Sets members penalty, if queuename=NULL we set member penalty in all the queues.
+ * \param[in] queuename If specified, only act on a member if it belongs to this queue
+ * \param[in] interface Interface of queue member(s) having priority set.
+ * \param[in] penalty Value penalty is being changed to for each member
+ */
static int set_member_penalty(const char *queuename, const char *interface, int penalty)
{
int foundinterface = 0, foundqueue = 0;
struct call_queue *q;
- struct member *mem;
- char rtpenalty[80];
+ struct ast_config *queue_config = NULL;
+ struct ao2_iterator queue_iter;
if (penalty < 0 && !negative_penalty_invalid) {
ast_log(LOG_ERROR, "Invalid penalty (%d)\n", penalty);
return RESULT_FAILURE;
}
- if ((q = load_realtime_queue(queuename))) {
- foundqueue++;
- ao2_lock(q);
- if ((mem = interface_exists(q, interface))) {
- foundinterface++;
- if (!mem->realtime) {
- mem->penalty = penalty;
- } else {
- sprintf(rtpenalty,"%i", penalty);
- update_realtime_member_field(mem, q->name, "penalty", rtpenalty);
+ if (ast_strlen_zero(queuename)) { /* This means we need to iterate through all the queues. */
+ if (ast_check_realtime("queues")) {
+ char *queuename;
+ queue_config = ast_load_realtime_multientry("queues", "name LIKE", "%", SENTINEL);
+ if (queue_config) {
+ for (queuename = ast_category_browse(queue_config, NULL); !ast_strlen_zero(queuename); queuename = ast_category_browse(queue_config, queuename)) {
+ if ((q = find_load_queue_rt_friendly(queuename))) {
+ foundqueue++;
+ foundinterface += set_member_penalty_help_members(q, interface, penalty);
+ }
+ }
}
- ast_queue_log(q->name, "NONE", interface, "PENALTY", "%d", penalty);
- manager_event(EVENT_FLAG_AGENT, "QueueMemberPenalty",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "Penalty: %d\r\n",
- q->name, mem->interface, penalty);
- ao2_ref(mem, -1);
}
- ao2_unlock(q);
+
+ /* After hitting realtime queues, go back and get the regular ones. */
+ queue_iter = ao2_iterator_init(queues, 0);
+
+ while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
+ foundqueue++;
+ foundinterface += set_member_penalty_help_members(q, interface, penalty);
+ }
+
+ } else { /* We actually have a queuename, so we can just act on the single queue. */
+ if ((q = find_load_queue_rt_friendly(queuename))) {
+ foundqueue++;
+ foundinterface += set_member_penalty_help_members(q, interface, penalty);
+ }
}
if (foundinterface) {
return RESULT_SUCCESS;
} else if (!foundqueue) {
- ast_log (LOG_ERROR, "Invalid queuename\n");
+ ast_log (LOG_ERROR, "Invalid queuename\n");
} else {
ast_log (LOG_ERROR, "Invalid interface\n");
}
}
if (!cur_queue) {
- cur_queue = load_realtime_queue(queue_name);
+ cur_queue = find_load_queue_rt_friendly(queue_name);
}
if (!cur_queue) {
ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
return -1;
}
- q = load_realtime_queue(data);
+ q = find_load_queue_rt_friendly(data);
snprintf(buf, len, "%d", q != NULL? 1 : 0);
if (q) {
queue_t_unref(q, "Done with temporary reference in QUEUE_EXISTS()");
AST_STANDARD_APP_ARGS(args, data);
- if ((q = load_realtime_queue(args.queuename))) {
+ if ((q = find_load_queue_rt_friendly(args.queuename))) {
ao2_lock(q);
if (!strcasecmp(args.option, "logged")) {
mem_iter = ao2_iterator_init(q->members, 0);
ast_log(LOG_ERROR, "Invalid interface, queue or penalty\n");
return -1;
}
- } else if ((q = load_realtime_queue(args.queuename))) {
+ } else if ((q = find_load_queue_rt_friendly(args.queuename))) {
ao2_lock(q);
if ((m = interface_exists(q, args.interface))) {
sprintf(rtvalue, "%s",(memvalue <= 0) ? "0" : "1");
return -1;
}
- if ((q = load_realtime_queue(data))) {
+ if ((q = find_load_queue_rt_friendly(data))) {
ao2_lock(q);
mem_iter = ao2_iterator_init(q->members, 0);
while ((m = ao2_iterator_next(&mem_iter))) {
}
if (argc == 3) { /* specific queue */
- if ((q = load_realtime_queue(argv[2]))) {
+ if ((q = find_load_queue_rt_friendly(argv[2]))) {
queue_t_unref(q, "Done with temporary pointer");
}
} else if (ast_check_realtime("queues")) {
char *queuename;
if (cfg) {
for (queuename = ast_category_browse(cfg, NULL); !ast_strlen_zero(queuename); queuename = ast_category_browse(cfg, queuename)) {
- if ((q = load_realtime_queue(queuename))) {
+ if ((q = find_load_queue_rt_friendly(queuename))) {
queue_t_unref(q, "Done with temporary pointer");
}
}
* been deleted from the in-core container
*/
if (q->realtime) {
- realtime_queue = load_realtime_queue(q->name);
+ realtime_queue = find_load_queue_rt_friendly(q->name);
if (!realtime_queue) {
ao2_unlock(q);
queue_t_unref(q, "Done with iterator");
for (queuename = ast_category_browse(cfg, NULL);
!ast_strlen_zero(queuename);
queuename = ast_category_browse(cfg, queuename)) {
- if ((queue = load_realtime_queue(queuename))) {
+ if ((queue = find_load_queue_rt_friendly(queuename))) {
queue_unref(queue);
}
}
while ((queue = ao2_iterator_next(&i))) {
ao2_lock(queue);
if (queue->realtime) {
- queue_realtime = load_realtime_queue(queue->name);
+ queue_realtime = find_load_queue_rt_friendly(queue->name);
if (!queue_realtime) {
ao2_unlock(queue);
queue_unref(queue);
struct member *mem = NULL;
struct call_queue *q;
- if ((q = load_realtime_queue(queuename))) {
+ if ((q = find_load_queue_rt_friendly(queuename))) {
ao2_lock(q);
mem = ao2_find(q->members, interface, OBJ_KEY);
ao2_unlock(q);