From: Walter Doekes Date: Tue, 16 Jun 2020 13:18:11 +0000 (+0200) Subject: app_queue: Read latest wrapuptime instead of (possibly stale) copy X-Git-Tag: 18.0.0-rc1~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0fb67383149e06869e66ad2fee0d0c7bab174a37;p=thirdparty%2Fasterisk.git 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 --- diff --git a/apps/app_queue.c b/apps/app_queue.c index 6ac5d891c6..b08f5cc55a 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -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)) {