[asterisk-commits] juggie: branch juggie/NoLossCDR r83396 - in /team/juggie/NoLossCDR: ./ apps/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 20 21:38:37 CDT 2007


Author: juggie
Date: Thu Sep 20 21:38:36 2007
New Revision: 83396

URL: http://svn.digium.com/view/asterisk?view=rev&rev=83396
Log:
Merged revisions 83283,83304,83325,83359,83386 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/team/group/CDRfix5

........
r83283 | root | 2007-09-20 15:07:52 -0400 (Thu, 20 Sep 2007) | 1 line

automerge commit
........
r83304 | root | 2007-09-20 16:07:52 -0400 (Thu, 20 Sep 2007) | 1 line

automerge commit
........
r83325 | root | 2007-09-20 17:08:27 -0400 (Thu, 20 Sep 2007) | 1 line

automerge commit
........
r83359 | root | 2007-09-20 18:08:24 -0400 (Thu, 20 Sep 2007) | 1 line

automerge commit
........
r83386 | root | 2007-09-20 20:07:49 -0400 (Thu, 20 Sep 2007) | 1 line

automerge commit
........

Modified:
    team/juggie/NoLossCDR/   (props changed)
    team/juggie/NoLossCDR/apps/app_minivm.c
    team/juggie/NoLossCDR/apps/app_playback.c
    team/juggie/NoLossCDR/apps/app_queue.c
    team/juggie/NoLossCDR/channels/chan_sip.c
    team/juggie/NoLossCDR/contrib/scripts/safe_asterisk
    team/juggie/NoLossCDR/doc/modules.txt
    team/juggie/NoLossCDR/main/app.c
    team/juggie/NoLossCDR/main/asterisk.c
    team/juggie/NoLossCDR/main/astmm.c
    team/juggie/NoLossCDR/main/dsp.c

Propchange: team/juggie/NoLossCDR/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/juggie/NoLossCDR/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Sep 20 21:38:36 2007
@@ -1,1 +1,1 @@
-/team/group/CDRfix5:1-83278
+/team/group/CDRfix5:1-83395

Modified: team/juggie/NoLossCDR/apps/app_minivm.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_minivm.c?view=diff&rev=83396&r1=83395&r2=83396
==============================================================================
--- team/juggie/NoLossCDR/apps/app_minivm.c (original)
+++ team/juggie/NoLossCDR/apps/app_minivm.c Thu Sep 20 21:38:36 2007
@@ -463,7 +463,7 @@
 static char *message_template_parse_emailbody(const char *body);
 static int create_vmaccount(char *name, struct ast_variable *var, int realtime);
 static struct minivm_account *find_user_realtime(const char *domain, const char *username);
-static int handle_minivm_reload(int fd, int argc, char *argv[]);
+static char *handle_minivm_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 /*! \brief Create message template */
 static struct minivm_template *message_template_create(const char *name)
@@ -2484,50 +2484,37 @@
 	return 0;
 }
 
-static const char minivm_show_users_help[] =
-"Usage: minivm list accounts\n"
-"       Lists all mailboxes currently set up\n";
-
-static const char minivm_show_zones_help[] =
-"Usage: minivm list zones\n"
-"       Lists zone message formats\n";
-
-static const char minivm_list_templates_help[] =
-"Usage: minivm list templates\n"
-"       Lists message templates for e-mail, paging and IM\n";
-
-static const char minivm_show_stats_help[] =
-"Usage: minivm show stats\n"
-"       Display Mini-Voicemail counters\n";
-
-static const char minivm_show_settings_help[] =
-"Usage: minivm show settings\n"
-"       Display Mini-Voicemail general settings\n";
-
-static const char minivm_reload_help[] =
-"Usage: minivm reload\n"
-"       Reload mini-voicemail configuration and reset statistics\n";
-
 /*! \brief CLI routine for listing templates */
-static int handle_minivm_list_templates(int fd, int argc, char *argv[])
+static char *handle_minivm_list_templates(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct minivm_template *this;
 	char *output_format = "%-15s %-10s %-10s %-15.15s %-50s\n";
 	int count = 0;
 
-	if (argc > 3)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "minivm list templates";
+		e->usage =
+			"Usage: minivm list templates\n"
+			"       Lists message templates for e-mail, paging and IM\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc > 3)
+		return CLI_SHOWUSAGE;
 
 	AST_LIST_LOCK(&message_templates);
 	if (AST_LIST_EMPTY(&message_templates)) {
-		ast_cli(fd, "There are no message templates defined\n");
+		ast_cli(a->fd, "There are no message templates defined\n");
 		AST_LIST_UNLOCK(&message_templates);
-		return RESULT_FAILURE;
-	}
-	ast_cli(fd, output_format, "Template name", "Charset", "Locale", "Attach media", "Subject");
-	ast_cli(fd, output_format, "-------------", "-------", "------", "------------", "-------");
+		return CLI_FAILURE;
+	}
+	ast_cli(a->fd, output_format, "Template name", "Charset", "Locale", "Attach media", "Subject");
+	ast_cli(a->fd, output_format, "-------------", "-------", "------", "------------", "-------");
 	AST_LIST_TRAVERSE(&message_templates, this, list) {
-		ast_cli(fd, output_format, this->name, 
+		ast_cli(a->fd, output_format, this->name, 
 			this->charset ? this->charset : "-", 
 			this->locale ? this->locale : "-",
 			this->attachment ? "Yes" : "No",
@@ -2535,75 +2522,9 @@
 		count++;
 	}
 	AST_LIST_UNLOCK(&message_templates);
-	ast_cli(fd, "\n * Total: %d minivoicemail message templates\n", count);
-	return RESULT_SUCCESS;
-}
-
-/*! \brief CLI command to list voicemail accounts */
-static int handle_minivm_show_users(int fd, int argc, char *argv[])
-{
-	struct minivm_account *vmu;
-	char *output_format = "%-23s %-15s %-15s %-10s %-10s %-50s\n";
-	int count = 0;
-
-	if ((argc < 3) || (argc > 5) || (argc == 4))
-		return RESULT_SHOWUSAGE;
-	if ((argc == 5) && strcmp(argv[3],"for"))
-		return RESULT_SHOWUSAGE;
-
-	AST_LIST_LOCK(&minivm_accounts);
-	if (AST_LIST_EMPTY(&minivm_accounts)) {
-		ast_cli(fd, "There are no voicemail users currently defined\n");
-		AST_LIST_UNLOCK(&minivm_accounts);
-		return RESULT_FAILURE;
-	}
-	ast_cli(fd, output_format, "User", "E-Template", "P-template", "Zone", "Format", "Full name");
-	ast_cli(fd, output_format, "----", "----------", "----------", "----", "------", "---------");
-	AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) {
-		char tmp[256] = "";
-
-
-		if ((argc == 3) || ((argc == 5) && !strcmp(argv[4], vmu->domain))) {
-			count++;
-			snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain);
-			ast_cli(fd, output_format, tmp, vmu->etemplate ? vmu->etemplate : "-", 
-				vmu->ptemplate ? vmu->ptemplate : "-",
-				vmu->zonetag ? vmu->zonetag : "-", 
-				vmu->attachfmt ? vmu->attachfmt : "-",
-				vmu->fullname);
-		}
-	}
-	AST_LIST_UNLOCK(&minivm_accounts);
-	ast_cli(fd, "\n * Total: %d minivoicemail accounts\n", count);
-	return RESULT_SUCCESS;
-}
-
-/*! \brief Show a list of voicemail zones in the CLI */
-static int handle_minivm_show_zones(int fd, int argc, char *argv[])
-{
-	struct minivm_zone *zone;
-	char *output_format = "%-15s %-20s %-45s\n";
-	int res = RESULT_SUCCESS;
-
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-
-	AST_LIST_LOCK(&minivm_zones);
-	if (!AST_LIST_EMPTY(&minivm_zones)) {
-		ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
-		ast_cli(fd, output_format, "----", "--------", "--------------");
-		AST_LIST_TRAVERSE(&minivm_zones, zone, list) {
-			ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
-		}
-	} else {
-		ast_cli(fd, "There are no voicemail zones currently defined\n");
-		res = RESULT_FAILURE;
-	}
-	AST_LIST_UNLOCK(&minivm_zones);
-
-	return res;
-}
-
+	ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count);
+	return CLI_SUCCESS;
+}
 
 static char *complete_minivm_show_users(const char *line, const char *word, int pos, int state)
 {
@@ -2612,7 +2533,7 @@
 	struct minivm_account *vmu;
 	const char *domain = "";
 
-	/* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <domain> */
+	/* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
 	if (pos > 4)
 		return NULL;
 	if (pos == 3)
@@ -2629,53 +2550,161 @@
 	return NULL;
 }
 
+/*! \brief CLI command to list voicemail accounts */
+static char *handle_minivm_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	struct minivm_account *vmu;
+	char *output_format = "%-23s %-15s %-15s %-10s %-10s %-50s\n";
+	int count = 0;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "minivm list accounts";
+		e->usage =
+			"Usage: minivm list accounts\n"
+			"       Lists all mailboxes currently set up\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_minivm_show_users(a->line, a->word, a->pos, a->n);
+	}
+
+	if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
+		return CLI_SHOWUSAGE;
+	if ((a->argc == 5) && strcmp(a->argv[3],"for"))
+		return CLI_SHOWUSAGE;
+
+	AST_LIST_LOCK(&minivm_accounts);
+	if (AST_LIST_EMPTY(&minivm_accounts)) {
+		ast_cli(a->fd, "There are no voicemail users currently defined\n");
+		AST_LIST_UNLOCK(&minivm_accounts);
+		return CLI_FAILURE;
+	}
+	ast_cli(a->fd, output_format, "User", "E-Template", "P-template", "Zone", "Format", "Full name");
+	ast_cli(a->fd, output_format, "----", "----------", "----------", "----", "------", "---------");
+	AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) {
+		char tmp[256] = "";
+		if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) {
+			count++;
+			snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain);
+			ast_cli(a->fd, output_format, tmp, vmu->etemplate ? vmu->etemplate : "-", 
+				vmu->ptemplate ? vmu->ptemplate : "-",
+				vmu->zonetag ? vmu->zonetag : "-", 
+				vmu->attachfmt ? vmu->attachfmt : "-",
+				vmu->fullname);
+		}
+	}
+	AST_LIST_UNLOCK(&minivm_accounts);
+	ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count);
+	return CLI_SUCCESS;
+}
+
+/*! \brief Show a list of voicemail zones in the CLI */
+static char *handle_minivm_show_zones(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	struct minivm_zone *zone;
+	char *output_format = "%-15s %-20s %-45s\n";
+	char *res = CLI_SUCCESS;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "minivm list zones";
+		e->usage =
+			"Usage: minivm list zones\n"
+			"       Lists zone message formats\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
+	AST_LIST_LOCK(&minivm_zones);
+	if (!AST_LIST_EMPTY(&minivm_zones)) {
+		ast_cli(a->fd, output_format, "Zone", "Timezone", "Message Format");
+		ast_cli(a->fd, output_format, "----", "--------", "--------------");
+		AST_LIST_TRAVERSE(&minivm_zones, zone, list) {
+			ast_cli(a->fd, output_format, zone->name, zone->timezone, zone->msg_format);
+		}
+	} else {
+		ast_cli(a->fd, "There are no voicemail zones currently defined\n");
+		res = CLI_FAILURE;
+	}
+	AST_LIST_UNLOCK(&minivm_zones);
+
+	return res;
+}
+
 /*! \brief CLI Show settings */
-static int handle_minivm_show_settings(int fd, int argc, char *argv[])
-{
-	ast_cli(fd, "* Mini-Voicemail general settings\n");
-	ast_cli(fd, "  -------------------------------\n");
-	ast_cli(fd, "\n");
-	ast_cli(fd, "  Mail command (shell):               %s\n", global_mailcmd);
-	ast_cli(fd, "  Max silence:                        %d\n", global_maxsilence);
-	ast_cli(fd, "  Silence treshold:                   %d\n", global_silencethreshold);
-	ast_cli(fd, "  Max message length (secs):          %d\n", global_vmmaxmessage);
-	ast_cli(fd, "  Min message length (secs):          %d\n", global_vmminmessage);
-	ast_cli(fd, "  Default format:                     %s\n", default_vmformat);
-	ast_cli(fd, "  Extern notify (shell):              %s\n", global_externnotify);
-	ast_cli(fd, "  Logfile:                            %s\n", global_logfile[0] ? global_logfile : "<disabled>");
-	ast_cli(fd, "  Operator exit:                      %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No");
-	ast_cli(fd, "  Message review:                     %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No");
-
-	ast_cli(fd, "\n");
-	return RESULT_SUCCESS;
+static char *handle_minivm_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "minivm show settings";
+		e->usage =
+			"Usage: minivm show settings\n"
+			"       Display Mini-Voicemail general settings\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	ast_cli(a->fd, "* Mini-Voicemail general settings\n");
+	ast_cli(a->fd, "  -------------------------------\n");
+	ast_cli(a->fd, "\n");
+	ast_cli(a->fd, "  Mail command (shell):               %s\n", global_mailcmd);
+	ast_cli(a->fd, "  Max silence:                        %d\n", global_maxsilence);
+	ast_cli(a->fd, "  Silence treshold:                   %d\n", global_silencethreshold);
+	ast_cli(a->fd, "  Max message length (secs):          %d\n", global_vmmaxmessage);
+	ast_cli(a->fd, "  Min message length (secs):          %d\n", global_vmminmessage);
+	ast_cli(a->fd, "  Default format:                     %s\n", default_vmformat);
+	ast_cli(a->fd, "  Extern notify (shell):              %s\n", global_externnotify);
+	ast_cli(a->fd, "  Logfile:                            %s\n", global_logfile[0] ? global_logfile : "<disabled>");
+	ast_cli(a->fd, "  Operator exit:                      %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No");
+	ast_cli(a->fd, "  Message review:                     %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No");
+
+	ast_cli(a->fd, "\n");
+	return CLI_SUCCESS;
 }
 
 /*! \brief Show stats */
-static int handle_minivm_show_stats(int fd, int argc, char *argv[])
+static char *handle_minivm_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ast_tm time;
 	char buf[BUFSIZ];
 
-	ast_cli(fd, "* Mini-Voicemail statistics\n");
-	ast_cli(fd, "  -------------------------\n");
-	ast_cli(fd, "\n");
-	ast_cli(fd, "  Voicemail accounts:                  %5d\n", global_stats.voicemailaccounts);
-	ast_cli(fd, "  Templates:                           %5d\n", global_stats.templates);
-	ast_cli(fd, "  Timezones:                           %5d\n", global_stats.timezones);
+	switch (cmd) {
+	
+	case CLI_INIT:
+		e->command = "minivm show stats";
+		e->usage =
+			"Usage: minivm show stats\n"
+			"       Display Mini-Voicemail counters\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	ast_cli(a->fd, "* Mini-Voicemail statistics\n");
+	ast_cli(a->fd, "  -------------------------\n");
+	ast_cli(a->fd, "\n");
+	ast_cli(a->fd, "  Voicemail accounts:                  %5d\n", global_stats.voicemailaccounts);
+	ast_cli(a->fd, "  Templates:                           %5d\n", global_stats.templates);
+	ast_cli(a->fd, "  Timezones:                           %5d\n", global_stats.timezones);
 	if (global_stats.receivedmessages == 0) {
-		ast_cli(fd, "  Received messages since last reset:  <none>\n");
+		ast_cli(a->fd, "  Received messages since last reset:  <none>\n");
 	} else {
-		ast_cli(fd, "  Received messages since last reset:  %d\n", global_stats.receivedmessages);
+		ast_cli(a->fd, "  Received messages since last reset:  %d\n", global_stats.receivedmessages);
 		ast_localtime(&global_stats.lastreceived, &time, NULL);
 		ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &time);
-		ast_cli(fd, "  Last received voicemail:             %s\n", buf);
+		ast_cli(a->fd, "  Last received voicemail:             %s\n", buf);
 	}
 	ast_localtime(&global_stats.reset, &time, NULL);
 	ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &time);
-	ast_cli(fd, "  Last reset:                          %s\n", buf);
-
-	ast_cli(fd, "\n");
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "  Last reset:                          %s\n", buf);
+
+	ast_cli(a->fd, "\n");
+	return CLI_SUCCESS;
 }
 
 /*! \brief  ${MINIVMACCOUNT()} Dialplan function - reads account data */
@@ -2963,29 +2992,12 @@
 
 /*! \brief CLI commands for Mini-voicemail */
 static struct ast_cli_entry cli_minivm[] = {
-	{ { "minivm", "list", "accounts", NULL },
-	handle_minivm_show_users, "List defined mini-voicemail boxes",
-	minivm_show_users_help, complete_minivm_show_users, NULL },
-
-	{ { "minivm", "list", "zones", NULL },
-	handle_minivm_show_zones, "List zone message formats",
-	minivm_show_zones_help, NULL, NULL },
-
-	{ { "minivm", "list", "templates", NULL },
-	handle_minivm_list_templates, "List message templates",
-	minivm_list_templates_help, NULL, NULL },
-
-	{ { "minivm", "reload", NULL, NULL },
-	handle_minivm_reload, "Reload Mini-voicemail configuration",
-	minivm_reload_help, NULL, NULL },
-
-	{ { "minivm", "show", "stats", NULL },
-	handle_minivm_show_stats, "Show some mini-voicemail statistics",
-	minivm_show_stats_help, NULL, NULL },
-
-	{ { "minivm", "show", "settings", NULL },
-	handle_minivm_show_settings, "Show mini-voicemail general settings",
-	minivm_show_settings_help, NULL, NULL },
+	NEW_CLI(handle_minivm_show_users, "List defined mini-voicemail boxes"),
+	NEW_CLI(handle_minivm_show_zones, "List zone message formats"),
+	NEW_CLI(handle_minivm_list_templates, "List message templates"),	
+	NEW_CLI(handle_minivm_reload, "Reload Mini-voicemail configuration"),
+	NEW_CLI(handle_minivm_show_stats, "Show some mini-voicemail statistics"),
+	NEW_CLI(handle_minivm_show_settings, "Show mini-voicemail general settings"),
 };
 
 static struct ast_custom_function minivm_counter_function = {
@@ -3061,11 +3073,23 @@
 }
 
 /*! \brief Reload cofiguration */
-static int handle_minivm_reload(int fd, int argc, char *argv[])
-{
+static char *handle_minivm_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "minivm reload";
+		e->usage =
+			"Usage: minivm reload\n"
+			"       Reload mini-voicemail configuration and reset statistics\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	
 	reload();
-	ast_cli(fd, "\n-- Mini voicemail re-configured \n");
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "\n-- Mini voicemail re-configured \n");
+	return CLI_SUCCESS;
 }
 
 /*! \brief Unload mini voicemail module */

Modified: team/juggie/NoLossCDR/apps/app_playback.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_playback.c?view=diff&rev=83396&r1=83395&r2=83396
==============================================================================
--- team/juggie/NoLossCDR/apps/app_playback.c (original)
+++ team/juggie/NoLossCDR/apps/app_playback.c Thu Sep 20 21:38:36 2007
@@ -75,14 +75,6 @@
 static const void *say_api_buf[40];
 static const char *say_old = "old";
 static const char *say_new = "new";
-static const char say_load_usage[] = 
-"Usage: say load [new|old]\n"
-"       say load\n"
-"	   Report status of current say mode\n"
-"       say load new\n"
-"          Set say method, configured in say.conf\n"
-"       say load old\n"
-"          Set old say metod, coded in asterisk core\n";
 
 static void save_say_mode(const void *arg)
 {
@@ -366,17 +358,31 @@
 }
 
 
-static int __say_cli_init(int fd, int argc, char *argv[])
+static char *__say_cli_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	const char *old_mode = say_api_buf[0] ? say_new : say_old;
 	char *mode;
-
-	if (argc == 2) {
-		ast_cli(fd, "say mode is [%s]\n", old_mode);
-		return RESULT_SUCCESS;
-        } else if (argc != 3)
-                return RESULT_SHOWUSAGE;
-        mode = argv[2];
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "say load [new|old]";
+		e->usage = 
+			"Usage: say load [new|old]\n"
+			"       say load\n"
+			"	   Report status of current say mode\n"
+			"       say load new\n"
+			"          Set say method, configured in say.conf\n"
+			"       say load old\n"
+			"          Set old say metod, coded in asterisk core\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc == 2) {
+		ast_cli(a->fd, "say mode is [%s]\n", old_mode);
+		return CLI_SUCCESS;
+        } else if (a->argc != 3)
+                return CLI_SHOWUSAGE;
+        mode = a->argv[2];
 	
 	if (!strcmp(mode, old_mode)) {
 		ast_log(LOG_NOTICE, "say mode is %s already\n", mode);
@@ -385,23 +391,13 @@
 			ast_log(LOG_NOTICE, "init say.c from %s to %s\n", old_mode, mode);
 		}
 	}
-
-	return RESULT_SUCCESS;
-}
-
+	return CLI_SUCCESS;
+}
 
 static struct ast_cli_entry cli_playback[] = {
-        { { "say", "load", NULL },
-	__say_cli_init, "Set or show the say mode",
-	say_load_usage },
-
-        { { "say", "load", "new", NULL },
-	__say_cli_init, "Set the say mode",
-	say_load_usage },
-
-        { { "say", "load", "old", NULL },
-	__say_cli_init, "Set the say mode",
-	say_load_usage },
+	NEW_CLI(__say_cli_init, "Set or show the say mode"),
+	NEW_CLI(__say_cli_init, "Set the say mode"),
+	NEW_CLI(__say_cli_init, "Set the say mode"),
 };
 
 static int playback_exec(struct ast_channel *chan, void *data)

Modified: team/juggie/NoLossCDR/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/apps/app_queue.c?view=diff&rev=83396&r1=83395&r2=83396
==============================================================================
--- team/juggie/NoLossCDR/apps/app_queue.c (original)
+++ team/juggie/NoLossCDR/apps/app_queue.c Thu Sep 20 21:38:36 2007
@@ -120,6 +120,7 @@
 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /* The minimum number of seconds between position announcements
                                              The default value of 15 provides backwards compatibility */
+#define MAX_QUEUE_BUCKETS 53
 
 #define	RES_OKAY	0		/* Action completed */
 #define	RES_EXISTS	(-1)		/* Entry already exists */
@@ -350,7 +351,6 @@
 #define QUEUE_EVENT_VARIABLES 3
 
 struct call_queue {
-	ast_mutex_t lock;	
 	char name[80];                      /*!< Name */
 	char moh[80];                       /*!< Music On Hold class to be used */
 	char announce[80];                  /*!< Announcement to play when call is answered */
@@ -422,7 +422,7 @@
 	AST_LIST_ENTRY(call_queue) list;    /*!< Next call queue */
 };
 
-static AST_LIST_HEAD_STATIC(queues, call_queue);
+static struct ao2_container *queues;
 
 static void update_realtime_members(struct call_queue *q);
 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
@@ -461,6 +461,30 @@
 	}
 
 	return -1;
+}
+
+static int queue_hash_cb(const void *obj, const int flags)
+{
+	const struct call_queue *q = obj;
+	return ast_str_hash(q->name);
+}
+
+static int queue_cmp_cb(void *obj, void *arg, int flags)
+{
+	struct call_queue *q = obj, *q2 = arg;
+	return !strcasecmp(q->name, q2->name) ? CMP_MATCH : 0;
+}
+
+static inline struct call_queue *queue_ref(struct call_queue *q)
+{
+	ao2_ref(q, 1);
+	return q;
+}
+
+static inline struct call_queue *queue_unref(struct call_queue *q)
+{
+	ao2_ref(q, -1);
+	return q;
 }
 
 static void set_queue_variables(struct queue_ent *qe)
@@ -516,7 +540,7 @@
 	struct ao2_iterator mem_iter;
 	enum queue_member_status result = QUEUE_NO_MEMBERS;
 
-	ast_mutex_lock(&q->lock);
+	ao2_lock(q);
 	mem_iter = ao2_iterator_init(q->members, 0);
 	for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
 		if (max_penalty && (member->penalty > max_penalty))
@@ -534,7 +558,7 @@
 			if (member->paused) {
 				result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
 			} else {
-				ast_mutex_unlock(&q->lock);
+				ao2_unlock(q);
 				ao2_ref(member, -1);
 				return QUEUE_NORMAL;
 			}
@@ -542,7 +566,7 @@
 		}
 	}
 
-	ast_mutex_unlock(&q->lock);
+	ao2_unlock(q);
 	return result;
 }
 
@@ -558,6 +582,7 @@
 	struct member *cur;
 	struct ao2_iterator mem_iter;
 	struct member_interface *curint;
+	struct ao2_iterator queue_iter;
 	char *loc;
 	char *technology;
 
@@ -589,9 +614,9 @@
 	}
 
 	ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
-	AST_LIST_LOCK(&queues);
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		ast_mutex_lock(&q->lock);
+	queue_iter = ao2_iterator_init(queues, 0);
+	while ((q = ao2_iterator_next(&queue_iter))) {
+		ao2_lock(q);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((cur = ao2_iterator_next(&mem_iter))) {
 			char *interface;
@@ -628,9 +653,9 @@
 			}
 			ao2_ref(cur, -1);
 		}
-		ast_mutex_unlock(&q->lock);
-	}
-	AST_LIST_UNLOCK(&queues);
+		queue_unref(q);
+		ao2_unlock(q);
+	}
 
 	return NULL;
 }
@@ -734,16 +759,6 @@
 	return cur;
 }
 
-static struct call_queue *alloc_queue(const char *queuename)
-{
-	struct call_queue *q;
-
-	if ((q = ast_calloc(1, sizeof(*q)))) {
-		ast_mutex_init(&q->lock);
-		ast_copy_string(q->name, queuename, sizeof(q->name));
-	}
-	return q;
-}
 
 static int compress_char(const char c)
 {
@@ -857,22 +872,23 @@
 {
 	struct call_queue *q;
 	struct member *mem, tmpmem;
+	struct ao2_iterator queue_iter;
 	int ret = 0;
 
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-
-	AST_LIST_LOCK(&queues);
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		ast_mutex_lock(&q->lock);
+	queue_iter = ao2_iterator_init(queues, 0);
+	while ((q = ao2_iterator_next(&queue_iter))) {
+
+		ao2_lock(q);
 		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
 			ao2_ref(mem, -1);
-			ret = 1;
-		}
-		ast_mutex_unlock(&q->lock);
-		if (ret)
+			ao2_unlock(q);
+			queue_unref(q);
 			break;
-	}
-	AST_LIST_UNLOCK(&queues);
+		}
+		ao2_unlock(q);
+		queue_unref(q);
+	}
 
 	return ret;
 }
@@ -1137,12 +1153,22 @@
 	}
 }
 
-static void destroy_queue(struct call_queue *q)
-{
+static void destroy_queue(void *obj)
+{
+	struct call_queue *q = obj;
+	ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
 	free_members(q, 1);
-	ast_mutex_destroy(&q->lock);
 	ao2_ref(q->members, -1);
-	free(q);
+}
+
+static struct call_queue *alloc_queue(const char *queuename)
+{
+	struct call_queue *q;
+
+	if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
+		ast_copy_string(q->name, queuename, sizeof(q->name));
+	}
+	return q;
 }
 
 /*!\brief Reload a single queue via realtime.
@@ -1151,7 +1177,7 @@
 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
 {
 	struct ast_variable *v;
-	struct call_queue *q;
+	struct call_queue *q, tmpq;
 	struct member *m;
 	struct ao2_iterator mem_iter;
 	char *interface = NULL;
@@ -1159,24 +1185,23 @@
 	char tmpbuf[64];	/* Must be longer than the longest queue param name. */
 
 	/* Find the queue in the in-core list (we will create a new one if not found). */
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		if (!strcasecmp(q->name, queuename))
-			break;
-	}
+	ast_copy_string(tmpq.name, queuename, sizeof(tmpq.name));
 
 	/* Static queues override realtime. */
-	if (q) {
-		ast_mutex_lock(&q->lock);
+	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+		ao2_lock(q);
 		if (!q->realtime) {
 			if (q->dead) {
-				ast_mutex_unlock(&q->lock);
+				ao2_unlock(q);
+				queue_unref(q);
 				return NULL;
 			} else {
 				ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
-				ast_mutex_unlock(&q->lock);
+				ao2_unlock(q);
 				return q;
 			}
 		}
+		queue_unref(q);
 	} else if (!member_config)
 		/* Not found in the list, and it's not realtime ... */
 		return NULL;
@@ -1192,13 +1217,9 @@
 
 			q->dead = 1;
 			/* Delete if unused (else will be deleted when last caller leaves). */
-			if (!q->count) {
-				/* Delete. */
-				AST_LIST_REMOVE(&queues, q, list);
-				ast_mutex_unlock(&q->lock);
-				destroy_queue(q);
-			} else
-				ast_mutex_unlock(&q->lock);
+			ao2_unlink(queues, q);
+			ao2_unlock(q);
+			queue_unref(q);
 		}
 		return NULL;
 	}
@@ -1207,11 +1228,12 @@
 	if (!q) {
 		if (!(q = alloc_queue(queuename)))
 			return NULL;
-		ast_mutex_lock(&q->lock);
+		ao2_lock(q);
 		clear_queue(q);
 		q->realtime = 1;
 		init_queue(q);		/* Ensure defaults for all parameters not set explicitly. */
-		AST_LIST_INSERT_HEAD(&queues, q, list);
+		ao2_link(queues, q);
+		queue_ref(q);
 	}
 
 	memset(tmpbuf, 0, sizeof(tmpbuf));
@@ -1250,15 +1272,15 @@
 	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->dead) {
 			ao2_unlink(q->members, m);
-			ast_mutex_unlock(&q->lock);
+			ao2_unlock(q);
 			remove_from_interfaces(m->interface);
-			ast_mutex_lock(&q->lock);
+			ao2_lock(q);
 			q->membercount--;
 		}
 		ao2_ref(m, -1);
 	}
 
-	ast_mutex_unlock(&q->lock);
+	ao2_unlock(q);
 
 	return q;
 }
@@ -1267,16 +1289,11 @@
 {
 	struct ast_variable *queue_vars;
 	struct ast_config *member_config = NULL;
-	struct call_queue *q;
+	struct call_queue *q = NULL, tmpq;
 
 	/* Find the queue in the in-core list first. */
-	AST_LIST_LOCK(&queues);
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		if (!strcasecmp(q->name, queuename)) {
-			break;
-		}
-	}
-	AST_LIST_UNLOCK(&queues);
+	ast_copy_string(tmpq.name, queuename, sizeof(tmpq.name));
+	q = ao2_find(queues, &tmpq, OBJ_POINTER);
 
 	if (!q || q->realtime) {
 		/*! \note Load from realtime before taking the global qlock, to avoid blocking all
@@ -1297,15 +1314,14 @@
 			}
 		}
 
-		AST_LIST_LOCK(&queues);
-
+		ao2_lock(queues);
 		q = find_queue_by_name_rt(queuename, queue_vars, member_config);
 		if (member_config)
 			ast_config_destroy(member_config);
 		if (queue_vars)
 			ast_variables_destroy(queue_vars);
-
-		AST_LIST_UNLOCK(&queues);
+		ao2_unlock(queues);
+
 	} else {
 		update_realtime_members(q);
 	}
@@ -1345,7 +1361,7 @@
 		return;
 	}
 
-	ast_mutex_lock(&q->lock);
+	ao2_lock(q);
 	
 	/* Temporarily set realtime  members dead so we can detect deleted ones.*/ 
 	mem_iter = ao2_iterator_init(q->members, 0);
@@ -1367,14 +1383,14 @@
 	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->dead) {
 			ao2_unlink(q->members, m);
-			ast_mutex_unlock(&q->lock);
+			ao2_unlock(q);
 			remove_from_interfaces(m->interface);
-			ast_mutex_lock(&q->lock);
+			ao2_lock(q);
 			q->membercount--;
 		}
 		ao2_ref(m, -1);
 	}
-	ast_mutex_unlock(&q->lock);
+	ao2_unlock(q);
 }
 
 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
@@ -1389,8 +1405,8 @@
 	if (!(q = load_realtime_queue(queuename)))
 		return res;
 
-	AST_LIST_LOCK(&queues);
-	ast_mutex_lock(&q->lock);
+	ao2_lock(queues);
+	ao2_lock(q);
 
 	/* This is our one */
 	stat = get_member_status(q, qe->max_penalty);
@@ -1437,8 +1453,8 @@
 			q->name, qe->pos, q->count, qe->chan->uniqueid );
 		ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
 	}
-	ast_mutex_unlock(&q->lock);
-	AST_LIST_UNLOCK(&queues);
+	ao2_unlock(q);
+	ao2_unlock(queues);
 
 	return res;
 }
@@ -1611,10 +1627,10 @@
 	/* Thanks to SRT for this contribution */
 	/* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
 
-	ast_mutex_lock(&qe->parent->lock);
+	ao2_lock(qe->parent);
 	oldvalue = qe->parent->holdtime;
 	qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
-	ast_mutex_unlock(&qe->parent->lock);
+	ao2_unlock(qe->parent);
 }
 
 
@@ -1626,7 +1642,8 @@
 
 	if (!(q = qe->parent))
 		return;
-	ast_mutex_lock(&q->lock);
+	queue_ref(q);
+	ao2_lock(q);
 
 	prev = NULL;
 	for (cur = q->head; cur; cur = cur->next) {
@@ -1649,15 +1666,20 @@
 			prev = cur;
 		}
 	}
-	ast_mutex_unlock(&q->lock);
-
-	if (q->dead && !q->count) {	
+	ao2_unlock(q);
+
+	/*If the queue is a realtime queue, check to see if it's still defined in real time*/
+	if(q->realtime) {
+		if(!ast_load_realtime("queues", "name", q->name, NULL))
+			q->dead = 1;
+	}
+
+	if (q->dead) {	
 		/* It's dead and nobody is in it, so kill it */
-		AST_LIST_LOCK(&queues);
-		AST_LIST_REMOVE(&queues, q, list);
-		AST_LIST_UNLOCK(&queues);
-		destroy_queue(q);
-	}
+		ao2_unlink(queues, q);
+		queue_unref(q);
+	}
+	queue_unref(q);
 }
 
 /* Hang up a list of outgoing calls */
@@ -1684,7 +1706,7 @@
 
 	/* Since a reload could have taken place, we have to traverse the list to
 		be sure it's still valid */
-	ast_mutex_lock(&q->lock);
+	ao2_lock(q);
 	mem_iter = ao2_iterator_init(q->members, 0);
 	while ((cur = ao2_iterator_next(&mem_iter))) {
 		if (member != cur) {
@@ -1709,7 +1731,7 @@
 		}
 		ao2_ref(cur, -1);
 	}
-	ast_mutex_unlock(&q->lock);
+	ao2_unlock(q);
 	return 0;
 }
 
@@ -1733,13 +1755,17 @@
 	struct call_queue *q;
 	struct member *mem;
 	int found = 0;
+	struct ao2_iterator queue_iter;
 	
 	/* &qlock and &rq->lock already set by try_calling()
 	 * to solve deadlock */
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		if (q == rq) /* don't check myself, could deadlock */
+	queue_iter = ao2_iterator_init(queues, 0);
+	while ((q = ao2_iterator_next(&queue_iter))) {
+		if (q == rq) { /* don't check myself, could deadlock */
+			queue_unref(q);
 			continue;
-		ast_mutex_lock(&q->lock);
+		}
+		ao2_lock(q);
 		if (q->count && q->members) {
 			if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
 				ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
@@ -1750,9 +1776,12 @@
 				ao2_ref(mem, -1);
 			}
 		}
-		ast_mutex_unlock(&q->lock);
-		if (found)
+		ao2_unlock(q);
+		if (found) {
+			queue_unref(q);
 			break;
+		}
+		queue_unref(q);
 	}
 	return found;
 }
@@ -1857,9 +1886,9 @@
 		tmp->stillgoing = 0;
 		update_dial_status(qe->parent, tmp->member, status);
 
-		ast_mutex_lock(&qe->parent->lock);
+		ao2_lock(qe->parent);
 		qe->parent->rrpos++;
-		ast_mutex_unlock(&qe->parent->lock);
+		ao2_unlock(qe->parent);
 
 		(*busies)++;
 		return 0;
@@ -2039,7 +2068,7 @@
 
 static void record_abandoned(struct queue_ent *qe)
 {
-	ast_mutex_lock(&qe->parent->lock);
+	ao2_lock(qe->parent);
 	set_queue_variables(qe);
 	manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
 		"Queue: %s\r\n"
@@ -2050,7 +2079,7 @@
 		qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
 
 	qe->parent->callsabandoned++;
-	ast_mutex_unlock(&qe->parent->lock);
+	ao2_unlock(qe->parent);
 }
 
 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
@@ -2280,8 +2309,9 @@
 			if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
 				/* Got hung up */
 				*to = -1;
-				if (f)
+				if (f) {
 					ast_frfree(f);
+				}
 				return NULL;
 			}
 			if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
@@ -2335,7 +2365,7 @@
 
 	} else {
 		/* This needs a lock. How many members are available to be served? */
-		ast_mutex_lock(&qe->parent->lock);
+		ao2_lock(qe->parent);
 			
 		ch = qe->parent->head;
 	
@@ -2372,7 +2402,7 @@
 			res = 0;
 		}
 		
-		ast_mutex_unlock(&qe->parent->lock);
+		ao2_unlock(qe->parent);
 	}
 
 	return res;
@@ -2443,13 +2473,13 @@
 
 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
 {
-	ast_mutex_lock(&q->lock);
+	ao2_lock(q);
 	time(&member->lastcall);
 	member->calls++;
 	q->callscompleted++;
 	if (callcompletedinsl)
 		q->callscompletedinsl++;
-	ast_mutex_unlock(&q->lock);
+	ao2_unlock(q);
 	return 0;
 }
 
@@ -2618,8 +2648,8 @@
 
 	/* Hold the lock while we setup the outgoing calls */
 	if (use_weight)
-		AST_LIST_LOCK(&queues);
-	ast_mutex_lock(&qe->parent->lock);
+		ao2_lock(queues);
+	ao2_lock(qe->parent);
 	ast_debug(1, "%s is trying to call a queue member.\n",
 							qe->chan->name);
 	ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
@@ -2634,9 +2664,9 @@
 
 		if (!tmp) {
 			ao2_ref(cur, -1);
-			ast_mutex_unlock(&qe->parent->lock);
+			ao2_unlock(qe->parent);
 			if (use_weight)
-				AST_LIST_UNLOCK(&queues);
+				ao2_unlock(queues);
 			goto out;
 		}
 		tmp->stillgoing = -1;
@@ -2666,15 +2696,15 @@
 		to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
 	orig = to;
 	ring_one(qe, outgoing, &numbusies);
-	ast_mutex_unlock(&qe->parent->lock);
+	ao2_unlock(qe->parent);
 	if (use_weight)
-		AST_LIST_UNLOCK(&queues);
+		ao2_unlock(queues);
 	lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
-	ast_mutex_lock(&qe->parent->lock);
+	ao2_lock(qe->parent);
 	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
 		store_next(qe, outgoing);
 	}
-	ast_mutex_unlock(&qe->parent->lock);
+	ao2_unlock(qe->parent);
 	peer = lpeer ? lpeer->chan : NULL;
 	if (!peer) {
 		if (to) {
@@ -2698,9 +2728,9 @@
 		/* Update parameters for the queue */
 		time(&now);
 		recalc_holdtime(qe, (now - qe->start));
-		ast_mutex_lock(&qe->parent->lock);
+		ao2_lock(qe->parent);
 		callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
-		ast_mutex_unlock(&qe->parent->lock);
+		ao2_unlock(qe->parent);
 		member = lpeer->member;
 		hangupcalls(outgoing, peer);
 		outgoing = NULL;
@@ -2782,7 +2812,7 @@
 				ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
 		}
 
-		ast_mutex_lock(&qe->parent->lock);
+		ao2_lock(qe->parent);
 		/* if setinterfacevar is defined, make member variables available to the channel */
 		/* use  pbx_builtin_setvar to set a load of variables with one call */
 		if (qe->parent->setinterfacevar) {
@@ -2801,7 +2831,7 @@
 	
 		/* try to set queue variables if configured to do so*/
 		set_queue_variables(qe);
-		ast_mutex_unlock(&qe->parent->lock);
+		ao2_unlock(qe->parent);
 		
 		/* Begin Monitoring */
 		if (qe->parent->monfmt && *qe->parent->monfmt) {
@@ -3131,20 +3161,14 @@
 
 static int remove_from_queue(const char *queuename, const char *interface)
 {
-	struct call_queue *q;
+	struct call_queue *q, tmpq;
 	struct member *mem, tmpmem;
 	int res = RES_NOSUCHQUEUE;
 
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-
-	AST_LIST_LOCK(&queues);
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		ast_mutex_lock(&q->lock);
-		if (strcmp(q->name, queuename)) {
-			ast_mutex_unlock(&q->lock);
-			continue;
-		}
-
+	ast_copy_string(tmpq.name, queuename, sizeof(tmpq.name));
+	if((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+		ao2_lock(q);
 		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK))) {
 			q->membercount--;
 			manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
@@ -3161,14 +3185,12 @@
 		} else {
 			res = RES_EXISTS;
 		}
-		ast_mutex_unlock(&q->lock);
-		break;
+		ao2_unlock(q);
+		queue_unref(q);
 	}
 
 	if (res == RES_OKAY)
 		remove_from_interfaces(interface);
-
-	AST_LIST_UNLOCK(&queues);
 
 	return res;
 }
@@ -3185,9 +3207,9 @@
 	if (!(q = load_realtime_queue(queuename)))
 		return res;
 
-	AST_LIST_LOCK(&queues);
-
-	ast_mutex_lock(&q->lock);
+	ao2_lock(queues);
+
+	ao2_lock(q);
 	if ((old_member = interface_exists(q, interface)) == NULL) {
 		add_to_interfaces(interface);
 		if ((new_member = create_queue_member(interface, membername, penalty, paused))) {
@@ -3220,8 +3242,8 @@
 		ao2_ref(old_member, -1);
 		res = RES_EXISTS;
 	}
-	ast_mutex_unlock(&q->lock);
-	AST_LIST_UNLOCK(&queues);
+	ao2_unlock(q);
+	ao2_unlock(queues);
 
 	return res;
 }
@@ -3231,15 +3253,16 @@
 	int found = 0;
 	struct call_queue *q;
 	struct member *mem;
+	struct ao2_iterator queue_iter;
 
 	/* Special event for when all queues are paused - individual events still generated */
 	/* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
 	if (ast_strlen_zero(queuename))
 		ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
 
-	AST_LIST_LOCK(&queues);
-	AST_LIST_TRAVERSE(&queues, q, list) {
-		ast_mutex_lock(&q->lock);
+	queue_iter = ao2_iterator_init(queues, 0);
+	while((q = ao2_iterator_next(&queue_iter))) {
+		ao2_lock(q);
 		if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
 			if ((mem = interface_exists(q, interface))) {
 				found++;
@@ -3275,9 +3298,9 @@
 				ao2_ref(mem, -1);
 			}
 		}
-		ast_mutex_unlock(&q->lock);
-	}
-	AST_LIST_UNLOCK(&queues);
+		ao2_unlock(q);
+		queue_unref(q);
+	}
 
 	return found ? RESULT_SUCCESS : RESULT_FAILURE;
 }
@@ -3296,10 +3319,10 @@
 	int paused = 0;
 	struct ast_db_entry *db_tree;
 	struct ast_db_entry *entry;
-	struct call_queue *cur_queue;

[... 826 lines stripped ...]



More information about the asterisk-commits mailing list