mirror of
https://github.com/asterisk/asterisk.git
synced 2026-07-28 00:10:25 -07:00
app_queue: Read latest wrapuptime instead of (possibly stale) copy
Before this changeset, it was possible that a queue member (agent) was called even though they just got out of a call, and wrapuptime seconds hadn't passed yet. This could happen if a member ended a call _between_ a new call attempt and asterisk trying that particular member for a new call. In that case, Asterisk would check the hangup time of the call-before-the-last-call instead of the hangup time of the-last-call. ASTERISK-28952 Change-Id: Ie0cab8f0e8d639c01cba633d4968ba19873d80b3
This commit is contained in:
+16
-19
@@ -1543,8 +1543,6 @@ struct callattempt {
|
||||
struct ast_channel *chan;
|
||||
char interface[256]; /*!< An Asterisk dial string (not a channel name) */
|
||||
int metric;
|
||||
time_t lastcall;
|
||||
struct call_queue *lastqueue;
|
||||
struct member *member;
|
||||
/*! Saved connected party info from an AST_CONTROL_CONNECTED_LINE. */
|
||||
struct ast_party_connected_line connected;
|
||||
@@ -4386,42 +4384,43 @@ static int member_status_available(int status)
|
||||
*/
|
||||
static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
|
||||
{
|
||||
struct member *memberp = call->member;
|
||||
int wrapuptime;
|
||||
|
||||
if (call->member->paused) {
|
||||
if (memberp->paused) {
|
||||
ast_debug(1, "%s paused, can't receive call\n", call->interface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!call->member->ringinuse && !member_status_available(call->member->status)) {
|
||||
if (!memberp->ringinuse && !member_status_available(memberp->status)) {
|
||||
ast_debug(1, "%s not available, can't receive call\n", call->interface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (call->lastqueue) {
|
||||
wrapuptime = get_wrapuptime(call->lastqueue, call->member);
|
||||
if (memberp->lastqueue) {
|
||||
wrapuptime = get_wrapuptime(memberp->lastqueue, memberp);
|
||||
} else {
|
||||
wrapuptime = get_wrapuptime(qe->parent, call->member);
|
||||
wrapuptime = get_wrapuptime(qe->parent, memberp);
|
||||
}
|
||||
if (wrapuptime && time(NULL) - call->lastcall < wrapuptime) {
|
||||
if (wrapuptime && (time(NULL) - memberp->lastcall) < wrapuptime) {
|
||||
ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
|
||||
(call->lastqueue ? call->lastqueue->name : qe->parent->name),
|
||||
(memberp->lastqueue ? memberp->lastqueue->name : qe->parent->name),
|
||||
call->interface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_weight && compare_weight(qe->parent, call->member)) {
|
||||
if (use_weight && compare_weight(qe->parent, memberp)) {
|
||||
ast_debug(1, "Priority queue delaying call to %s:%s\n",
|
||||
qe->parent->name, call->interface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!call->member->ringinuse) {
|
||||
if (!memberp->ringinuse) {
|
||||
struct member *mem;
|
||||
|
||||
ao2_lock(pending_members);
|
||||
|
||||
mem = ao2_find(pending_members, call->member,
|
||||
mem = ao2_find(pending_members, memberp,
|
||||
OBJ_SEARCH_OBJECT | OBJ_NOLOCK);
|
||||
if (mem) {
|
||||
/*
|
||||
@@ -4439,8 +4438,8 @@ static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
|
||||
* If not found add it to the container so another queue
|
||||
* won't attempt to call this member at the same time.
|
||||
*/
|
||||
ast_debug(3, "Add %s to pending_members\n", call->member->membername);
|
||||
ao2_link(pending_members, call->member);
|
||||
ast_debug(3, "Add %s to pending_members\n", memberp->membername);
|
||||
ao2_link(pending_members, memberp);
|
||||
ao2_unlock(pending_members);
|
||||
|
||||
/*
|
||||
@@ -4448,10 +4447,10 @@ static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
|
||||
* because the device state and extension state callbacks may
|
||||
* not have updated the status yet.
|
||||
*/
|
||||
if (!member_status_available(get_queue_member_status(call->member))) {
|
||||
if (!member_status_available(get_queue_member_status(memberp))) {
|
||||
ast_debug(1, "%s actually not available, can't receive call\n",
|
||||
call->interface);
|
||||
pending_members_remove(call->member);
|
||||
pending_members_remove(memberp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -6854,9 +6853,7 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
|
||||
|
||||
tmp->block_connected_update = block_connected_line;
|
||||
tmp->stillgoing = 1;
|
||||
tmp->member = cur;/* Place the reference for cur into callattempt. */
|
||||
tmp->lastcall = cur->lastcall;
|
||||
tmp->lastqueue = cur->lastqueue;
|
||||
tmp->member = cur; /* Place the reference for cur into callattempt. */
|
||||
ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
|
||||
/* Calculate the metric for the appropriate strategy. */
|
||||
if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
|
||||
|
||||
Reference in New Issue
Block a user