diff --git a/apps/app_queue.c b/apps/app_queue.c index 17c8c9a9a3..8e26135cd1 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2162,7 +2162,7 @@ static struct ast_json *queue_member_blob_create(struct call_queue *q, struct me * is available, the function immediately returns 0. If no members are available, * then -1 is returned. */ -static int get_member_status(struct call_queue *q, int max_penalty, int min_penalty, enum empty_conditions conditions) +static int get_member_status(struct call_queue *q, int max_penalty, int min_penalty, enum empty_conditions conditions, int devstate) { struct member *member; struct ao2_iterator mem_iter; @@ -2177,7 +2177,7 @@ static int get_member_status(struct call_queue *q, int max_penalty, int min_pena } } - switch (member->status) { + switch (devstate ? ast_device_state(member->state_interface) : member->status) { case AST_DEVICE_INVALID: if (conditions & QUEUE_EMPTY_INVALID) { ast_debug(4, "%s is unavailable because his device state is 'invalid'\n", member->membername); @@ -2227,8 +2227,12 @@ static int get_member_status(struct call_queue *q, int max_penalty, int min_pena } } ao2_iterator_destroy(&mem_iter); - ao2_unlock(q); + + if (!devstate && (conditions & QUEUE_EMPTY_RINGING)) { + /* member state still may be RINGING due to lag in event message - check again with device state */ + return get_member_status(q, max_penalty, min_penalty, conditions, 1); + } return -1; } @@ -3447,7 +3451,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * /* This is our one */ if (q->joinempty) { int status = 0; - if ((status = get_member_status(q, qe->max_penalty, qe->min_penalty, q->joinempty))) { + if ((status = get_member_status(q, qe->max_penalty, qe->min_penalty, q->joinempty, 0))) { *reason = QUEUE_JOINEMPTY; ao2_unlock(q); queue_t_unref(q, "Done with realtime queue"); @@ -5143,7 +5147,7 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r if (qe->parent->leavewhenempty) { int status = 0; - if ((status = get_member_status(qe->parent, qe->max_penalty, qe->min_penalty, qe->parent->leavewhenempty))) { + if ((status = get_member_status(qe->parent, qe->max_penalty, qe->min_penalty, qe->parent->leavewhenempty, 0))) { *reason = QUEUE_LEAVEEMPTY; ast_queue_log(qe->parent->name, ast_channel_uniqueid(qe->chan), "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start); leave_queue(qe); @@ -7806,7 +7810,7 @@ check_turns: if (qe.parent->leavewhenempty) { int status = 0; - if ((status = get_member_status(qe.parent, qe.max_penalty, qe.min_penalty, qe.parent->leavewhenempty))) { + if ((status = get_member_status(qe.parent, qe.max_penalty, qe.min_penalty, qe.parent->leavewhenempty, 0))) { record_abandoned(&qe); reason = QUEUE_LEAVEEMPTY; ast_queue_log(args.queuename, ast_channel_uniqueid(chan), "NONE", "EXITEMPTY", "%d|%d|%ld", qe.pos, qe.opos, (long)(time(NULL) - qe.start));