summaryrefslogtreecommitdiff
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authorkkm <kkm@smartaction.com>2017-01-24 20:31:38 -0800
committerKirill Katsnelson <kkm@smartaction.com>2017-01-26 20:21:15 -0600
commit8270d2436d927e6b5c9988538f665ada51b4f2dc (patch)
treeb213de6da25dc8220813de35a0dea5cc2ee67101 /apps/app_queue.c
parent10631bb209ff4edd7f0c0ff203e4c846059d899c (diff)
app_queue: Fix queues randomly disappearing on reload
With 500+ queues and a reload every minute, a random queue disappears upon reload. The cause is mususe of the 'dead' flag. Namely, all queues were marked dead up front, and then "resurrected" by dropping this flag for those found in the configuration. But a queue marked dead can be removed also when control leaves the app entry point on a PBX thread. With this change, the queue is marked only not found, and at the end of reload only the queues that are still not found are actually marked as dead, so the dead flag is never reset, and set only on positively dead queues. ASTERISK-26755 Change-Id: I3a4537aec9eb8d8aeeaa0193407e3523feb004bf
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c36
1 files changed, 8 insertions, 28 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index da24c51d6..344e9c1a5 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -9206,33 +9206,22 @@ static void reload_single_queue(struct ast_config *cfg, struct ast_flags *mask,
queue_t_unref(q, "Expiring creation reference");
}
-static int remove_members_and_mark_unfound(void *obj, void *arg, int flags)
+static int mark_unfound(void *obj, void *arg, int flags)
{
struct call_queue *q = obj;
char *queuename = arg;
if (!q->realtime && (ast_strlen_zero(queuename) || !strcasecmp(queuename, q->name))) {
q->found = 0;
-
}
return 0;
}
-static int mark_dead_and_unfound(void *obj, void *arg, int flags)
+static int kill_if_unfound(void *obj, void *arg, int flags)
{
struct call_queue *q = obj;
char *queuename = arg;
- if (!q->realtime && (ast_strlen_zero(queuename) || !strcasecmp(queuename, q->name))) {
+ if (!q->realtime && !q->found && (ast_strlen_zero(queuename) || !strcasecmp(queuename, q->name))) {
q->dead = 1;
- q->found = 0;
- }
- return 0;
-}
-
-static int kill_dead_queues(void *obj, void *arg, int flags)
-{
- struct call_queue *q = obj;
- char *queuename = arg;
- if ((ast_strlen_zero(queuename) || !strcasecmp(queuename, q->name)) && q->dead) {
return CMP_MATCH;
} else {
return 0;
@@ -9257,7 +9246,6 @@ static int reload_queues(int reload, struct ast_flags *mask, const char *queuena
char *cat;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
const int queue_reload = ast_test_flag(mask, QUEUE_RELOAD_PARAMETERS);
- const int member_reload = ast_test_flag(mask, QUEUE_RELOAD_MEMBER);
if (!(cfg = ast_config_load("queues.conf", config_flags))) {
ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
@@ -9272,18 +9260,10 @@ static int reload_queues(int reload, struct ast_flags *mask, const char *queuena
/* We've made it here, so it looks like we're doing operations on all queues. */
ao2_lock(queues);
- /* Mark all queues as dead for the moment if we're reloading queues.
- * For clarity, we could just be reloading members, in which case we don't want to mess
- * with the other queue parameters at all*/
- if (queue_reload) {
- ao2_callback(queues, OBJ_NODATA | OBJ_NOLOCK, mark_dead_and_unfound, (char *) queuename);
- }
-
- if (member_reload) {
- ao2_callback(queues, OBJ_NODATA, remove_members_and_mark_unfound, (char *) queuename);
- }
+ /* Mark non-realtime queues not found at the beginning. */
+ ao2_callback(queues, OBJ_NODATA, mark_unfound, (char *) queuename);
- /* Chug through config file */
+ /* Chug through config file. */
cat = NULL;
while ((cat = ast_category_browse(cfg, cat)) ) {
if (!strcasecmp(cat, "general") && queue_reload) {
@@ -9295,9 +9275,9 @@ static int reload_queues(int reload, struct ast_flags *mask, const char *queuena
}
ast_config_destroy(cfg);
- /* Unref all the dead queues if we were reloading queues */
if (queue_reload) {
- ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NOLOCK, kill_dead_queues, (char *) queuename);
+ /* Unlink and mark dead all non-realtime queues that were not found in the configuration file. */
+ ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NOLOCK, kill_if_unfound, (char *) queuename);
}
ao2_unlock(queues);
return 0;