aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-11-13 18:23:55 +0000
committerfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-11-13 18:23:55 +0000
commit46489d816d86e4b3083b71b13cee69409802c448 (patch)
treea88c9424a071d7c1ba610aaffe9e2e248a2d37a4 /apps
parentd9a503cf36d04bee53ea0b7acda5caa3a6424635 (diff)
Add 'loose' option to joinempty and leavewhenempty which is almost exactly like 'strict' except it does not count paused queue members as unavailable. (issue #8263 reported by gnarf)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@47567 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r--apps/app_queue.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 77ab09166..bdc5eefa4 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -338,6 +338,7 @@ static AST_LIST_HEAD_STATIC(interfaces, member_interface);
/* values used in multi-bit flags in call_queue */
#define QUEUE_EMPTY_NORMAL 1
#define QUEUE_EMPTY_STRICT 2
+#define QUEUE_EMPTY_LOOSE 3
#define ANNOUNCEHOLDTIME_ALWAYS 1
#define ANNOUNCEHOLDTIME_ONCE 2
#define QUEUE_EVENT_VARIABLES 3
@@ -488,6 +489,7 @@ static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, st
enum queue_member_status {
QUEUE_NO_MEMBERS,
QUEUE_NO_REACHABLE_MEMBERS,
+ QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
QUEUE_NORMAL
};
@@ -501,18 +503,22 @@ static enum queue_member_status get_member_status(struct call_queue *q, int max_
if (max_penalty && (member->penalty > max_penalty))
continue;
- if (member->paused) continue;
-
switch (member->status) {
case AST_DEVICE_INVALID:
/* nothing to do */
break;
case AST_DEVICE_UNAVAILABLE:
- result = QUEUE_NO_REACHABLE_MEMBERS;
+ if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)
+ result = QUEUE_NO_REACHABLE_MEMBERS;
break;
default:
- ast_mutex_unlock(&q->lock);
- return QUEUE_NORMAL;
+ if (member->paused) {
+ result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
+ } else {
+ ast_mutex_unlock(&q->lock);
+ return QUEUE_NORMAL;
+ }
+ break;
}
}
@@ -903,14 +909,18 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
q->strategy = QUEUE_STRATEGY_RINGALL;
}
} else if (!strcasecmp(param, "joinempty")) {
- if (!strcasecmp(val, "strict"))
+ if (!strcasecmp(val, "loose"))
+ q->joinempty = QUEUE_EMPTY_LOOSE;
+ else if (!strcasecmp(val, "strict"))
q->joinempty = QUEUE_EMPTY_STRICT;
else if (ast_true(val))
q->joinempty = QUEUE_EMPTY_NORMAL;
else
q->joinempty = 0;
} else if (!strcasecmp(param, "leavewhenempty")) {
- if (!strcasecmp(val, "strict"))
+ if (!strcasecmp(val, "loose"))
+ q->leavewhenempty = QUEUE_EMPTY_LOOSE;
+ else if (!strcasecmp(val, "strict"))
q->leavewhenempty = QUEUE_EMPTY_STRICT;
else if (ast_true(val))
q->leavewhenempty = QUEUE_EMPTY_NORMAL;
@@ -1189,7 +1199,9 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
stat = get_member_status(q, qe->max_penalty);
if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
*reason = QUEUE_JOINEMPTY;
- else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
+ else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
+ *reason = QUEUE_JOINUNAVAIL;
+ else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
*reason = QUEUE_JOINUNAVAIL;
else if (q->maxlen && (q->count >= q->maxlen))
*reason = QUEUE_FULL;
@@ -2207,7 +2219,13 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r
}
/* leave the queue if no reachable agents, if enabled */
- if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+ if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
+ *reason = QUEUE_LEAVEUNAVAIL;
+ ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
+ leave_queue(qe);
+ break;
+ }
+ if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
*reason = QUEUE_LEAVEUNAVAIL;
ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
leave_queue(qe);
@@ -3532,7 +3550,13 @@ check_turns:
}
/* leave the queue if no reachable agents, if enabled */
- if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
+ if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
+ record_abandoned(&qe);
+ reason = QUEUE_LEAVEUNAVAIL;
+ res = 0;
+ break;
+ }
+ if ((qe.parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
record_abandoned(&qe);
reason = QUEUE_LEAVEUNAVAIL;
res = 0;