diff --git a/apps/app_queue.c b/apps/app_queue.c index bb4c0cc3ea4a8349b33672d86663db77d241bf28..da813e435bf84e3714ed0f5d40effe20532d87e5 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1592,7 +1592,7 @@ static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, st * 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; @@ -1607,7 +1607,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); @@ -1657,8 +1657,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; } @@ -2967,7 +2971,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"); @@ -4812,7 +4816,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); @@ -7212,7 +7216,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));