Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 375015) +++ apps/app_queue.c (working copy) @@ -3411,6 +3411,38 @@ return vars; } +/* Lock/Unlock members with the same interface */ +static int lock_queue_member_by_interface (struct member *curm, int lock) { + struct ao2_iterator miter, qiter; + struct member *m; + struct call_queue *q; + + /* For all queues, lock all members with the same interface */ + qiter = ao2_iterator_init(queues, 0); + while ((q = ao2_t_iterator_next(&qiter, "Iterate through queues"))) { + ao2_lock(q); + miter = ao2_iterator_init(q->members, 0); + for (; (m = ao2_iterator_next(&miter)); ao2_ref(m, -1)) { + if (!strcmp(m->interface, curm->interface)) { + if (lock) { + ao2_lock(m); + ast_debug(1, "Locked %s in queue %s\n", m->interface, q->name); + } + else { + ao2_unlock(m); + ast_debug(1, "Unlocked %s in queue %s\n", m->interface, q->name); + } + ao2_ref(m, -1); + break; + } + } + ao2_iterator_destroy(&miter); + ao2_unlock(q); + queue_t_unref(q, "Done with iterator"); + } + return 0; +} + /*! * \brief Part 2 of ring_one * @@ -3576,9 +3608,9 @@ ast_channel_unlock(tmp->chan); ast_channel_unlock(qe->chan); - - ao2_lock(tmp->member); - update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member)); + + lock_queue_member_by_interface(tmp->member, 1); + update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member)); if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) { ast_verb(1, "Member %s is busy, cannot dial", tmp->member->interface); res = -1; @@ -3587,7 +3619,7 @@ /* Place the call, but don't wait on the answer */ res = ast_call(tmp->chan, location, 0); } - ao2_unlock(tmp->member); + lock_queue_member_by_interface(tmp->member, 0); if (res) { /* Again, keep going even if there's an error */ ast_verb(3, "Couldn't call %s\n", tmp->interface);