# Asterisks patch # ============================================== # - Fix strategy change to linear, convert the bucket list to a linear one # - Fix the order of static & dynamic agents after a reload --- asterisk/apps/app_queue.c +++ asterisk/apps/app_queue.c @@ -1700,6 +1700,26 @@ q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn); else q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn); + } else { + if (q->strategy == QUEUE_STRATEGY_LINEAR || q->strategy == QUEUE_STRATEGY_RRORDERED) { + /* convert the ao2 container for linear strategy */ + int count = 0; + struct ao2_container *members_new = ao2_container_alloc(1, member_hash_fn, member_cmp_fn); + struct member *cur; + + struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0); + while ((cur = ao2_iterator_next(&mem_iter))) { + ao2_link(members_new, cur); + ao2_unlink(q->members, cur); + ao2_ref(cur, -1); + count++; + } + ao2_iterator_destroy(&mem_iter); + + ao2_ref(q->members, -1); + q->members = members_new; + ast_log(LOG_NOTICE, "Changing to the linear/rrordered strategy. Converted %d members.\n", count); + } } q->found = 1; @@ -6717,6 +6737,43 @@ if (member_reload) { ao2_callback(q->members, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, kill_dead_members, q); } + + if (q->strategy == QUEUE_STRATEGY_LINEAR || q->strategy == QUEUE_STRATEGY_RRORDERED) { + /* move dynamic agents to the end */ + if (member_reload) { + ast_log(LOG_NOTICE, "reload_single_queue - move dynamic agents %s.\n", queuename); + struct ao2_iterator mem_iter; + struct member *mem; + + /* temporary dynamic container */ + struct ao2_container *dynamic = ao2_container_alloc(1, member_hash_fn, member_cmp_fn); + + /* find and remove dynamic agents */ + mem_iter = ao2_iterator_init(q->members, 0); + while ((mem = ao2_iterator_next(&mem_iter))) { + if (mem->dynamic) { + ast_log(LOG_NOTICE, "reload_single_queue dynamic remove %s.\n", mem->membername); + ao2_link(dynamic, mem); + ao2_unlink(q->members, mem); + } + ao2_ref(mem, -1); + } + ao2_iterator_destroy(&mem_iter); + + /* append dynamic agents */ + mem_iter = ao2_iterator_init(dynamic, 0); + while ((mem = ao2_iterator_next(&mem_iter))) { + ast_log(LOG_NOTICE, "reload_single_queue dynamic append %s.\n", mem->membername); + ao2_link(q->members, mem); + ao2_unlink(dynamic, mem); + ao2_ref(mem, -1); + } + ao2_iterator_destroy(&mem_iter); + + /* clean up */ + ao2_ref(dynamic, -1); + } + } if (new) { queues_t_link(queues, q, "Add queue to container");