Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 76874) +++ apps/app_queue.c (working copy) @@ -312,6 +312,7 @@ }; struct member { + ast_mutex_t member_lock; char interface[80]; /*!< Technology/Location */ char membername[80]; /*!< Member name to use in queue logs */ int penalty; /*!< Are we a last resort? */ @@ -621,6 +622,7 @@ struct member *cur; if ((cur = ast_calloc(1, sizeof(*cur)))) { + ast_mutex_init(&cur->member_lock); cur->penalty = penalty; cur->paused = paused; ast_copy_string(cur->interface, interface, sizeof(cur->interface)); @@ -973,15 +975,23 @@ for (curm = q->members; curm; curm = next) { next = curm->next; + ast_mutex_lock(&curm->member_lock); if (all || !curm->dynamic) { if (prev) prev->next = next; else q->members = next; remove_from_interfaces(curm->interface); + ast_mutex_unlock(&curm->member_lock); + usleep(1); + ast_mutex_lock(&curm->member_lock); + ast_mutex_unlock(&curm->member_lock); + ast_mutex_destroy(&curm->member_lock); free(curm); - } else + } else { + ast_mutex_unlock(&curm->member_lock); prev = curm; + } } } @@ -1093,6 +1103,7 @@ m = q->members; prev_m = NULL; while (m) { + ast_mutex_lock(&m->member_lock); next_m = m->next; if (m->dead) { if (prev_m) { @@ -1101,9 +1112,15 @@ q->members = next_m; } remove_from_interfaces(m->interface); + ast_mutex_unlock(&m->member_lock); + usleep(1); + ast_mutex_lock(&m->member_lock); + ast_mutex_unlock(&m->member_lock); + ast_mutex_destroy(&m->member_lock); free(m); } else { prev_m = m; + ast_mutex_unlock(&m->member_lock); } m = next_m; } @@ -2094,7 +2111,8 @@ if (!*to) rna(orig, qe, on, membername); } - + if(peer) + ast_mutex_lock(&peer->member->member_lock); return peer; } @@ -2497,6 +2515,7 @@ ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start); record_abandoned(qe); ast_hangup(peer); + ast_mutex_unlock(&member->member_lock); return -1; } } @@ -2512,6 +2531,7 @@ ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name); record_abandoned(qe); ast_hangup(peer); + ast_mutex_unlock(&member->member_lock); return -1; } /* Begin Monitoring */ @@ -2693,7 +2713,8 @@ } out: hangupcalls(outgoing, NULL); - + if(member) + ast_mutex_unlock(&member->member_lock); return res; } @@ -2776,11 +2797,15 @@ if ((last_member = interface_exists(q, interface))) { if ((look = q->members) == last_member) { + ast_mutex_lock(&last_member->member_lock); q->members = last_member->next; + ast_mutex_unlock(&last_member->member_lock); } else { while (look != NULL) { if (look->next == last_member) { + ast_mutex_lock(&last_member->member_lock); look->next = last_member->next; + ast_mutex_unlock(&last_member->member_lock); break; } else { look = look->next; @@ -2792,6 +2817,10 @@ "Location: %s\r\n" "MemberName: %s\r\n", q->name, last_member->interface, last_member->membername); + usleep(1); + ast_mutex_lock(&last_member->member_lock); + ast_mutex_unlock(&last_member->member_lock); + ast_mutex_destroy(&last_member->member_lock); free(last_member); if (queue_persistent_members) @@ -3826,6 +3855,7 @@ newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0); if (cur) { + ast_mutex_lock(&cur->member_lock); /* Delete it now */ newm->next = cur->next; if (prev) { @@ -3833,6 +3863,11 @@ } else { q->members = newm; } + ast_mutex_unlock(&cur->member_lock); + usleep(1); + ast_mutex_lock(&cur->member_lock); + ast_mutex_unlock(&cur->member_lock); + ast_mutex_destroy(&cur->member_lock); free(cur); } else { /* Add them to the master int list if necessary */ @@ -3849,6 +3884,7 @@ for (prev = NULL, cur = q->members; cur; cur = next) { + ast_mutex_lock(&cur->member_lock); next = cur->next; if (!cur->delme) { @@ -3862,6 +3898,11 @@ q->members = next; remove_from_interfaces(cur->interface); + ast_mutex_unlock(&cur->member_lock); + usleep(1); + ast_mutex_lock(&cur->member_lock); + ast_mutex_unlock(&cur->member_lock); + ast_mutex_destroy(&cur->member_lock); free(cur); }