[Asterisk-code-review] app queue: Fix queues randomly disappearing on reload (asterisk[master])

Kirill Katsnelson asteriskteam at digium.com
Wed Jan 25 23:08:12 CST 2017


Kirill Katsnelson has uploaded a new change for review. ( https://gerrit.asterisk.org/4829 )

Change subject: app_queue: Fix queues randomly disappearing on reload
......................................................................

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
---
M apps/app_queue.c
1 file changed, 6 insertions(+), 21 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/29/4829/1

diff --git a/apps/app_queue.c b/apps/app_queue.c
index da24c51..c00bebd 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -9206,33 +9206,22 @@
 	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;
@@ -9275,12 +9264,8 @@
 	/* 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);
+	if (queue_reload || member_reload) {
+		ao2_callback(queues, OBJ_NODATA, mark_unfound, (char *) queuename);
 	}
 
 	/* Chug through config file */
@@ -9297,7 +9282,7 @@
 	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);
+		ao2_callback(queues, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NOLOCK, kill_if_unfound, (char *) queuename);
 	}
 	ao2_unlock(queues);
 	return 0;

-- 
To view, visit https://gerrit.asterisk.org/4829
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3a4537aec9eb8d8aeeaa0193407e3523feb004bf
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Kirill Katsnelson <kkm at smartaction.com>



More information about the asterisk-code-review mailing list