[asterisk-commits] twilson: branch twilson/config_work r362137 - in /team/twilson/config_work: a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 13 22:57:28 CDT 2012


Author: twilson
Date: Fri Apr 13 22:57:24 2012
New Revision: 362137

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=362137
Log:
Add category "preload" support

Add the ability to preload certain categories. This allows evil
modules that propagate global default values to handle this via
the post_cfg_init callback.

Modified:
    team/twilson/config_work/apps/app_skel.c
    team/twilson/config_work/include/asterisk/config_options.h
    team/twilson/config_work/main/config_options.c

Modified: team/twilson/config_work/apps/app_skel.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/apps/app_skel.c?view=diff&rev=362137&r1=362136&r2=362137
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Fri Apr 13 22:57:24 2012
@@ -150,7 +150,7 @@
 	.module = AST_MODULE,
 	.filename = "app_skel.conf",
 	.apply_config = skel_apply_config,
-	.preload = "pvt3,general",
+/*	.preload = { "general", SENTINEL }, */
 };
 
 static void skel_global_config_destructor(void *obj)

Modified: team/twilson/config_work/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/config_options.h?view=diff&rev=362137&r1=362136&r2=362137
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Fri Apr 13 22:57:24 2012
@@ -90,10 +90,10 @@
 struct aco_info {
 	const char *module;
 	const char *filename;
-	const char *preload;
 	struct ao2_container *opts;
 	struct ao2_container *objs;
 	aco_apply_config apply_config;
+	const char *preload[]; /* Use a sentinel! */
 };
 
 /*! \brief The option types with default handlers

Modified: team/twilson/config_work/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/config_options.c?view=diff&rev=362137&r1=362136&r2=362137
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Fri Apr 13 22:57:24 2012
@@ -248,6 +248,103 @@
 	return ao2_callback(container, 0, config_opt_obj_context_cmp, (void *) context);
 }
 
+static int is_preload(struct aco_info *info, const char *cat)
+{
+	int i;
+
+	if (!info->preload) {
+		return 0;
+	}
+
+	for (i = 0; !ast_strlen_zero(info->preload[i]); i++) {
+		if (!strcasecmp(cat, info->preload[i])) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int process_category(struct ast_config *cfg, struct aco_info *info, const char *cat, int preload) {
+	RAII_VAR(void *, tmppvt, NULL, ao2_cleanup);
+	RAII_VAR(void *, tmpcfg, NULL, ao2_cleanup);
+	RAII_VAR(struct aco_type *, obj, ast_config_option_object_find(info->objs, cat), ao2_cleanup);
+
+	/* Skip preloaded categories if we aren't preloading */
+	if (!preload && is_preload(info, cat)) {
+		return 0;
+	}
+
+	/* Find config object by context, if not found it is an error */
+	if (!obj) {
+		ast_log(LOG_NOTICE, "2\n");
+		return -1;
+	}
+
+	/* if type == GLOBAL_OBJ, set defaults and configure the cached cfg object */
+	if (obj->type == GLOBAL_OBJ && obj->new_global_cfg) {
+		if (aco_set_defaults(info->opts, cat, obj->new_global_cfg)) {
+			ast_log(LOG_NOTICE, "3\n");
+			return -1;
+		}
+		if (aco_process_category_options(info->opts, cfg, cat, obj->new_global_cfg)) {
+			ast_log(LOG_NOTICE, "4\n");
+			return -1;
+		}
+	} else if (obj->type == PRIVATE_OBJ) {
+		/* If we've already linked a private for cat in newpvts, don't add a second one with the same name */
+		if (obj->new_pvts) {
+			if ((tmppvt = obj->find_pvt(obj->new_pvts, cat))) {
+				ast_log(LOG_NOTICE, "5\n");
+				return -1;
+			}
+
+			/* Get a ref to the existing private, or create a new one */
+			if (!(tmppvt = obj->find_or_create_pvt(cat))) {
+				/* Since we will be replacing the whole private container, bail out on errors instead of just
+				 * skipping privates with config errors */
+				ast_log(LOG_WARNING, "Could not create pvt '%s,' ignoring all private config changes.\n", cat);
+				return -1;
+			}
+		}
+
+		if (!(tmpcfg = obj->cfg_alloc(cat))) {
+			ast_log(LOG_NOTICE, "6\n");
+			return -1;
+		}
+
+		if (aco_set_defaults(info->opts, cat, tmpcfg)) {
+			ast_log(LOG_NOTICE, "7\n");
+			return -1;
+		}
+
+		if (obj->post_cfg_init && obj->post_cfg_init(tmpcfg)) {
+			ast_log(LOG_NOTICE, "8\n");
+			return -1;
+		}
+
+		if (aco_process_category_options(info->opts, cfg, cat, tmpcfg)) {
+			ast_log(LOG_NOTICE, "9\n");
+			return -1;
+		}
+
+		if (obj->prelink && obj->prelink(tmpcfg)) {
+			ast_log(LOG_NOTICE, "10\n");
+			return -1;
+		}
+
+		/* We have a valid pvt/cfg, link 'em */
+		if (tmppvt && !ao2_link(obj->new_pvts, tmppvt)) {
+			ast_log(LOG_NOTICE, "11\n");
+			return -1;
+		}
+		if (!ao2_link(obj->new_cfgs, tmpcfg)) {
+			ast_log(LOG_NOTICE, "12\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
 int aco_process_config(struct aco_info *info, int reload)
 {
 	struct ast_config *cfg;
@@ -275,91 +372,25 @@
 	}
 
 	ao2_callback(info->objs, OBJ_NODATA, allocate_temp_objects, &err);
+
 	if (err) {
 		ao2_callback(info->objs, OBJ_NODATA, cleanup_temp_objects, NULL);
 		ast_log(LOG_NOTICE, "1\n");
 		goto error;
 	}
 
-	while ((cat = ast_category_browse(cfg, cat))) {
-		RAII_VAR(void *, tmppvt, NULL, ao2_cleanup);
-		RAII_VAR(void *, tmpcfg, NULL, ao2_cleanup);
-		RAII_VAR(struct aco_type *, obj, ast_config_option_object_find(info->objs, cat), ao2_cleanup);
-
-		/* Find config object by context, if not found it is an error */
-		if (!obj) {
-			ast_log(LOG_NOTICE, "2\n");
-			goto error;
-		}
-
-		/* if type == GLOBAL_OBJ, set defaults and configure the cached cfg object */
-		if (obj->type == GLOBAL_OBJ && obj->new_global_cfg) {
-			if (aco_set_defaults(info->opts, cat, obj->new_global_cfg)) {
-				ast_log(LOG_NOTICE, "3\n");
+	if (info->preload) {
+		int i;
+		for (i = 0; !ast_strlen_zero(info->preload[i]); i++) {
+			if (process_category(cfg, info, info->preload[i], 1)) {
 				goto error;
 			}
-			if (aco_process_category_options(info->opts, cfg, cat, obj->new_global_cfg)) {
-				ast_log(LOG_NOTICE, "4\n");
-				goto error;
-			}
-		} else if (obj->type == PRIVATE_OBJ) {
-			/* If we've already linked a private for cat in newpvts, don't add a second one with the same name */
-			if (obj->new_pvts) {
-				if ((tmppvt = obj->find_pvt(obj->new_pvts, cat))) {
-					ast_log(LOG_NOTICE, "5\n");
-					goto error;
-				}
-
-				/* Get a ref to the existing private, or create a new one */
-				if (!(tmppvt = obj->find_or_create_pvt(cat))) {
-					/* Since we will be replacing the whole private container, bail out on errors instead of just
-					 * skipping privates with config errors */
-					ast_log(LOG_WARNING, "Could not create pvt '%s,' ignoring all private config changes.\n", cat);
-					goto error;
-				}
-			}
-
-			if (!(tmpcfg = obj->cfg_alloc(cat))) {
-				ast_log(LOG_NOTICE, "6\n");
-				goto error;
-			}
-
-			if (aco_set_defaults(info->opts, cat, tmpcfg)) {
-				ast_log(LOG_NOTICE, "7\n");
-				goto error;
-			}
-
-			/* XXX Might rename this callback to make it obvious it is after defaults
-			 * have been set. The purpose is to allow the module to override default
-			 * values based on other info, like what is in the various global settings
-			 * stored in info->objectsthe module to override default
-			 * values based on other info, like what is in the various global settings
-			 * stored in info->objects--but I'll have to implement preload support for
-			 * that to work first! TODO */
-			if (obj->post_cfg_init && obj->post_cfg_init(tmpcfg)) {
-				ast_log(LOG_NOTICE, "8\n");
-				goto error;
-			}
-
-			if (aco_process_category_options(info->opts, cfg, cat, tmpcfg)) {
-				ast_log(LOG_NOTICE, "9\n");
-				goto error;
-			}
-
-			if (obj->prelink && obj->prelink(tmpcfg)) {
-				ast_log(LOG_NOTICE, "10\n");
-				goto error;
-			}
-
-			/* We have a valid pvt/cfg, link 'em */
-			if (tmppvt && !ao2_link(obj->new_pvts, tmppvt)) {
-				ast_log(LOG_NOTICE, "11\n");
-				goto error;
-			}
-			if (!ao2_link(obj->new_cfgs, tmpcfg)) {
-				ast_log(LOG_NOTICE, "12\n");
-				goto error;
-			}
+		}
+	}
+
+	while ((cat = ast_category_browse(cfg, cat))) {
+		if (process_category(cfg, info, cat, 0)) {
+			goto error;
 		}
 	}
 




More information about the asterisk-commits mailing list