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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 10 10:28:04 CDT 2012


Author: twilson
Date: Thu May 10 10:27:57 2012
New Revision: 366047

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=366047
Log:
Some simplification work

This is just a checkin of work and nowhere near actual readyness. Just a backup.
Still need to clean up the ao2 global stuff, going to make aco_type a non-ao2 object
that is just stored in a list or array in the aco_info. Mostly I wanted to commit
this because even though it isn't clean, it still functions and I might want to
revert back to it after messing stuff up next. :-p


Modified:
    team/twilson/config_work/apps/app_skel.c
    team/twilson/config_work/include/asterisk/astobj2.h
    team/twilson/config_work/include/asterisk/config_options.h
    team/twilson/config_work/main/astobj2.c
    team/twilson/config_work/main/config_options.c
    team/twilson/config_work/main/udptl.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=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Thu May 10 10:27:57 2012
@@ -142,13 +142,10 @@
 #define PVT_BUCKETS 17
 
 static AO2_GLOBAL_OBJ_STATIC(global_config, NUM_GLOBAL_OBJECTS);
-AST_MUTEX_DEFINE_STATIC(reload_lock);
-
-static int skel_apply_config(void);
 
 CONFIG_INFO_STANDARD(cfg_info,
 	.filename = "app_skel.conf",
-	.apply_config = skel_apply_config,
+	.current_array = &global_config.global,
 );
 
 static void skel_global_config_destructor(void *obj)
@@ -247,23 +244,6 @@
 	} else {
 		return -1;
 	}
-
-	return 0;
-}
-
-static int skel_apply_config(void)
-{
-	RAII_VAR(void *, new_global, aco_info_new_global_get(&cfg_info, "global"), ao2_cleanup);
-	RAII_VAR(struct ao2_container *, new_pvts, aco_info_new_privates_get(&cfg_info, "private"), ao2_cleanup);
-	RAII_VAR(struct ao2_container *, new_cfgs, aco_info_new_configs_get(&cfg_info, "private"), ao2_cleanup);
-
-	if (!(new_global && new_pvts && new_cfgs)) {
-		return -1;
-	}
-
-	ao2_global_obj_replace_unref(global_config, GLOBAL_OPTIONS, new_global);
-	ao2_global_obj_replace_unref(global_config, PVT_CONTAINER, new_pvts);
-	ao2_global_obj_replace_unref(global_config, PVT_CFG_CONTAINER, new_cfgs);
 
 	return 0;
 }
@@ -474,12 +454,9 @@
 
 static int reload_module(void)
 {
-	ast_mutex_lock(&reload_lock);
 	if (aco_process_config(&cfg_info, 1)) {
-		ast_mutex_unlock(&reload_lock);
 		return AST_MODULE_LOAD_DECLINE;
 	}
-	ast_mutex_unlock(&reload_lock);
 
 	return 0;
 }
@@ -492,6 +469,28 @@
 	return ast_unregister_application(app);
 }
 
+static struct aco_type general_options = {
+	.type = GLOBAL_OBJ,
+	.name = "global",
+	.global_index = GLOBAL_OPTIONS,
+	.category_allow = ACO_WHITELIST,
+	.category = "general",
+	.cfg_alloc = (aco_type_alloc) skel_global_alloc,
+};
+
+static struct aco_type private_options = {
+	.type = PRIVATE_OBJ,
+	.name = "private",
+	.pvt_index = PVT_CONTAINER,
+	.cfg_index = PVT_CFG_CONTAINER,
+	.category_allow = ACO_BLACKLIST,
+	.category = "general",
+	.cfg_alloc = (aco_type_alloc) skel_pvt_cfg_alloc,
+	.containers_alloc = skel_containers_alloc,
+	.find_or_create_pvt = skel_find_or_create_pvt,
+	.find_pvt = skel_find_pvt,
+};
+
 static int load_module(void)
 {
 	RAII_VAR(struct aco_type *, global_type, NULL, ao2_cleanup);
@@ -501,16 +500,21 @@
 		goto error;
 	}
 
-	if (!(global_type = aco_type_global_alloc("global", ACO_WHITELIST, "general", (aco_type_alloc) skel_global_alloc))) {
-		goto error;
-	}
-
-	if (!(priv_type = aco_type_private_alloc("private", ACO_BLACKLIST, "general", NULL, NULL, (aco_type_alloc) skel_pvt_cfg_alloc, skel_containers_alloc, skel_find_or_create_pvt, skel_find_pvt, NULL, NULL))) {
-		goto error;
-	}
-
-	aco_type_register(&cfg_info, global_type);
-	aco_type_register(&cfg_info, priv_type);
+	if (!(global_type = aco_type_object(&general_options))) {
+		goto error;
+	}
+
+	if (!(priv_type = aco_type_object(&private_options))) {
+		goto error;
+	}
+
+	if (aco_type_register(&cfg_info, global_type)) {
+		goto error;
+	}
+
+	if (aco_type_register(&cfg_info, priv_type)) {
+		goto error;
+	}
 
 	/* General Options */
 	aco_option_register(&cfg_info, "foo", global_type, "booya", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, foo));
@@ -526,12 +530,9 @@
 	aco_option_register_custom(&cfg_info, "bit1", priv_type, "yes", custom_bitfield_handler, 0);
 	aco_option_register_custom(&cfg_info, "bit2", priv_type, "no", custom_bitfield_handler, 0);
 
-	ast_mutex_lock(&reload_lock);
 	if (aco_process_config(&cfg_info, 0)) {
-		ast_mutex_unlock(&reload_lock);
-		goto error;
-	}
-	ast_mutex_unlock(&reload_lock);
+		goto error;
+	}
 
 	ast_cli_register_multiple(skel_cli, ARRAY_LEN(skel_cli));
 	if (ast_register_application_xml(app, app_exec)) {

Modified: team/twilson/config_work/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/astobj2.h?view=diff&rev=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/include/asterisk/astobj2.h (original)
+++ team/twilson/config_work/include/asterisk/astobj2.h Thu May 10 10:27:57 2012
@@ -666,11 +666,11 @@
  * \retval NULL if no object available.
  */
 #define ao2_t_global_obj_replace(array, idx, obj, tag)	\
-	__ao2_global_obj_replace(&array.global, (idx), (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+	__ao2_global_obj_replace(&array.global, (idx), (obj), 1, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
 #define ao2_global_obj_replace(array, idx, obj)	\
-	__ao2_global_obj_replace(&array.global, (idx), (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
-
-void *__ao2_global_obj_replace(struct ao2_global_obj *array, unsigned int idx, void *obj, const char *tag, const char *file, int line, const char *func, const char *name);
+	__ao2_global_obj_replace(&array.global, (idx), (obj), 1, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+
+void *__ao2_global_obj_replace(struct ao2_global_obj *array, unsigned int idx, void *obj, int lock, const char *tag, const char *file, int line, const char *func, const char *name);
 
 /*!
  * \brief Replace a global ao2 object in the global array, throwing away any old object
@@ -689,11 +689,13 @@
  * \retval 1 The global object was not previously empty
  */
 #define ao2_t_global_obj_replace_unref(array, idx, obj, tag)	\
-	__ao2_global_obj_replace_unref(&array.global, (idx), (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+	__ao2_global_obj_replace_unref(&array.global, (idx), (obj), 1, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
 #define ao2_global_obj_replace_unref(array, idx, obj)	\
-	__ao2_global_obj_replace_unref(&array.global, (idx), (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
-int __ao2_global_obj_replace_unref(struct ao2_global_obj *array, unsigned int idx, void *obj, const char *tag, const char *file, int line, const char *func, const char *name);
-
+	__ao2_global_obj_replace_unref(&array.global, (idx), (obj), 1, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+int __ao2_global_obj_replace_unref(struct ao2_global_obj *array, unsigned int idx, void *obj, int lock, const char *tag, const char *file, int line, const char *func, const char *name);
+
+#define __ao2_global_obj_wrlock(array) __ast_rwlock_wrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, &array->lock, #array)
+#define __ao2_global_obj_unlock(array) __ast_rwlock_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, &array->lock, #array)
 /*!
  * \brief Get a reference to the object stored in the ao2 global array.
  * \since 11.0

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=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Thu May 10 10:27:57 2012
@@ -17,7 +17,7 @@
  */
 
 /*! \file
- * \brief Configuration Option-handling
+ * \brief Configuration option-handling
  * \author Terry Wilson <twilson at digium.com>
  */
 
@@ -47,6 +47,8 @@
 	ACO_WHITELIST,
 };
 
+struct aco_type *aco_type_object(struct aco_type *type);
+
 /* Callback functions for option parsing via aco_process_config() */
 
 /*! \brief Allocate a configurable ao2 object
@@ -104,6 +106,32 @@
  */
 typedef int (*aco_type_prelink)(void *newcfg);
 
+/*! \struct aco_type
+ * \brief Type information about a category-level configurable object
+ */
+struct aco_type {
+	/* common stuff */
+	enum aco_type_t type;
+	const char *name;
+	const char *category;
+	const char *matchfield;
+	const char *matchvalue;
+	regex_t *regex;
+	enum aco_category_op category_allow;
+	size_t global_index;
+	size_t pvt_index;
+	size_t cfg_index;
+	aco_type_alloc cfg_alloc;
+
+	/* non-global callbacks */
+	aco_type_containers_alloc containers_alloc; /* required. cfgs required, pvts if non-config-related state */
+	aco_type_find_or_create_pvt find_or_create_pvt; /* required if there is non-config-related state */
+	aco_type_find_pvt find_pvt; /* required if there is non-config-related state */
+	aco_type_post_cfg_init post_cfg_init; /*!< Filter global options done if necessary */
+	aco_type_prelink prelink; /* optional, can be used to do additional checks on a config */
+};
+
+
 /*! \brief Allocate a container for aco_types
  *
  * \note If using aco_process_config, this function is unnecessary as calling aco_info_init
@@ -121,6 +149,7 @@
  * are unique and not linked in a container
  *
  * \param name A unique identifier for this type
+ * \param global_index The index in the global object array for the global config
  * \param op Whether the following category regex is a whitelist or blacklist
  * \param category A regular expression for matching categories to be allowed or denied
  * \param alloc An allocation function for ao2 object associated with this type
@@ -128,14 +157,16 @@
  * \retval NULL error
  * \retval non-NULL A new global aco_type handle
  */
-struct aco_type *aco_type_global_alloc(const char *name, enum aco_category_op op, const char *category, aco_type_alloc alloc);
-
-/*! \brief Allocate a global config type
+struct aco_type *aco_type_global_alloc(const char *name, size_t global_index, enum aco_category_op op, const char *category, aco_type_alloc alloc);
+
+/*! \brief Allocate a private config type
  *
  * \note Use this to allocate private config types. These types are for configs that
  * are defined multiple times and stored in an ao2 container.
  *
  * \param name A unique identifier for this type
+ * \param pvt_index The index in the global object array for the private container
+ * \param cfg_index The index in the global object array for the private config container
  * \param op Whether the following category regex is a whitelist or blacklist
  * \param category A regular expression for matching categories to be allowed or denied
  * \param matchfield An option name to match for this type (i.e. a 'type'-like column)
@@ -150,7 +181,7 @@
  * \retval NULL error
  * \retval non-NULL A new private aco_type handle
  */
-struct aco_type *aco_type_private_alloc(const char *name, enum aco_category_op op, const char *category, const char *matchfield, const char *matchvalue,
+struct aco_type *aco_type_private_alloc(const char *name, size_t pvt_index, size_t cfg_index, enum aco_category_op op, const char *category, const char *matchfield, const char *matchvalue,
 	aco_type_alloc alloc, aco_type_containers_alloc containers_alloc, aco_type_find_or_create_pvt find_or_create_pvt,
 	aco_type_find_pvt find_pvt, aco_type_post_cfg_init post_cfg_init, aco_type_prelink prelink);
 
@@ -164,8 +195,10 @@
 	const char *module;
 	const char *filename;
 	struct ao2_container *opts;
-	struct ao2_container *objs;
+	struct ao2_container *types;
 	aco_apply_config apply_config;
+	struct ao2_global_obj *current_array;
+	void **new_array;
 	const char *preload[]; /* Use a sentinel! Even if preload is empty! */
 };
 

Modified: team/twilson/config_work/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/astobj2.c?view=diff&rev=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/main/astobj2.c (original)
+++ team/twilson/config_work/main/astobj2.c Thu May 10 10:27:57 2012
@@ -659,7 +659,7 @@
 	__ast_rwlock_unlock(file, line, func, &array->lock, name);
 }
 
-void *__ao2_global_obj_replace(struct ao2_global_obj *array, unsigned int idx, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
+void *__ao2_global_obj_replace(struct ao2_global_obj *array, unsigned int idx, void *obj, int lock, const char *tag, const char *file, int line, const char *func, const char *name)
 {
 	void *obj_old;
 
@@ -667,7 +667,7 @@
 		/* For sanity */
 		return NULL;
 	}
-	if (__ast_rwlock_wrlock(file, line, func, &array->lock, name)) {
+	if (lock && __ast_rwlock_wrlock(file, line, func, &array->lock, name)) {
 		/* Could not get the write lock. */
 		return NULL;
 	}
@@ -678,14 +678,16 @@
 	obj_old = array->obj[idx];
 	array->obj[idx] = obj;
 
-	__ast_rwlock_unlock(file, line, func, &array->lock, name);
+	if (lock) {
+		__ast_rwlock_unlock(file, line, func, &array->lock, name);
+	}
 
 	return obj_old;
 }
 
-int __ao2_global_obj_replace_unref(struct ao2_global_obj *array, unsigned int idx, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
-{
-	void *obj_old = __ao2_global_obj_replace(array, idx, obj, tag, file, line, func, name);
+int __ao2_global_obj_replace_unref(struct ao2_global_obj *array, unsigned int idx, void *obj, int lock, const char *tag, const char *file, int line, const char *func, const char *name)
+{
+	void *obj_old = __ao2_global_obj_replace(array, idx, obj, lock, tag, file, line, func, name);
 	if (obj_old) {
 		__ao2_ref_debug(obj_old, -1, tag, file, line, func);
 		return 1;

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=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Thu May 10 10:27:57 2012
@@ -39,35 +39,6 @@
 #define CONFIG_OPT_BUCKETS 53
 #endif /* LOW_MEMORY */
 
-/*! \struct aco_type
- * \brief Type information about a category-level configurable object
- */
-struct aco_type {
-	/* common stuff */
-	enum aco_type_t type;
-	const char *name;
-	const char *category;
-	const char *matchfield;
-	const char *matchvalue;
-	regex_t *regex;
-	enum aco_category_op category_allow;
-	aco_type_alloc cfg_alloc;
-
-	/* non-global callbacks */
-	aco_type_containers_alloc containers_alloc; /* required. cfgs required, pvts if non-config-related state */
-	aco_type_find_or_create_pvt find_or_create_pvt; /* required if there is non-config-related state */
-	aco_type_find_pvt find_pvt; /* required if there is non-config-related state */
-	aco_type_post_cfg_init post_cfg_init; /*!< Filter global options done if necessary */
-	aco_type_prelink prelink; /* optional, can be used to do additional checks on a config */
-
-	/* global cached object */
-	void *new_global_cfg; /* This is a cache and the reason we need locks */
-
-	/* non-global cached objects */
-	struct ao2_container *new_pvts; /* required if there is non-config-related state */
-	struct ao2_container *new_cfgs; /* required */
-};
-
 struct aco_option {
 	const char *name;
 	const char *default_val;
@@ -213,20 +184,21 @@
 	return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp);
 }
 
-static int allocate_temp_objects(void *o, void *arg, int flags)
-{
-	struct aco_type *obj = o;
-	int *error = arg;
-
-	switch (obj->type) {
+static int allocate_temp_objects(void *obj, void *arg, void *data, int flags)
+{
+	struct aco_type *t = obj;
+	struct aco_info *info = arg;
+	int *error = data;
+
+	switch (t->type) {
 	case GLOBAL_OBJ:
-		if (!(obj->new_global_cfg = obj->cfg_alloc(NULL))) {
+		if (!(info->new_array[t->global_index] = t->cfg_alloc(NULL))) {
 			*error = -1;
 			return CMP_STOP;
 		}
 		break;
 	case PRIVATE_OBJ:
-		if (obj->containers_alloc(&obj->new_pvts, &obj->new_cfgs)) {
+		if (t->containers_alloc((struct ao2_container **) &info->new_array[t->pvt_index], (struct ao2_container **) &info->new_array[t->cfg_index])) {
 			*error = -1;
 			return CMP_STOP;
 		}
@@ -237,26 +209,27 @@
 
 static int cleanup_temp_objects(void *obj, void *arg, int flags)
 {
-	struct aco_type *object = obj;
-	if (!object) {
+	struct aco_type *t = obj;
+	struct aco_info *info = arg;
+	if (!t) {
 		return 0;
 	}
 
-	switch (object->type) {
+	switch (t->type) {
 	case GLOBAL_OBJ:
-		if (object->new_global_cfg) {
-			ao2_ref(object->new_global_cfg, -1);
-			object->new_global_cfg = NULL;
+		if (info->new_array[t->global_index]) {
+			ao2_ref(info->new_array[t->global_index], -1);
+			info->new_array[t->global_index] = NULL;
 		}
 		break;
 	case PRIVATE_OBJ:
-		if (object->new_pvts) {
-			ao2_ref(object->new_pvts, -1);
-			object->new_pvts = NULL;
-		}
-		if (object->new_cfgs) {
-			ao2_ref(object->new_cfgs, -1);
-			object->new_cfgs = NULL;
+		if (info->new_array[t->pvt_index]) {
+			ao2_ref(info->new_array[t->pvt_index], -1);
+			info->new_array[t->pvt_index] = NULL;
+		}
+		if (info->new_array[t->cfg_index]) {
+			ao2_ref(info->new_array[t->cfg_index], -1);
+			info->new_array[t->cfg_index] = NULL;
 		}
 		break;
 	}
@@ -322,25 +295,25 @@
 	}
 
 	/* Find config object by category, if not found it is an error */
-	if (!(obj = internal_aco_type_find(info->objs, cfg, cat))) {
+	if (!(obj = internal_aco_type_find(info->types, cfg, cat))) {
 		ast_log(LOG_ERROR, "Could not find config type for category '%s' in '%s'\n", cat, info->filename);
 		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)) {
+	if (obj->type == GLOBAL_OBJ && info->new_array[obj->global_index]) {
+		if (aco_set_defaults(info->opts, cat, info->new_array[obj->global_index])) {
 			ast_log(LOG_ERROR, "In %s: Setting defaults for %s failed\n", info->filename, cat);
 			return -1;
 		}
-		if (aco_process_category_options(info->opts, cfg, cat, obj->new_global_cfg)) {
+		if (aco_process_category_options(info->opts, cfg, cat, info->new_array[obj->global_index])) {
 			ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", info->filename, cat);
 			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))) {
+		if (info->new_array[obj->pvt_index]) {
+			if ((tmppvt = obj->find_pvt(info->new_array[obj->pvt_index], cat))) {
 				ast_log(LOG_ERROR, "In %s: Multiple definitions of %s!\n", info->filename, cat);
 				return -1;
 			}
@@ -380,15 +353,28 @@
 		}
 
 		/* We have a valid pvt/cfg, link 'em */
-		if (tmppvt && !ao2_link(obj->new_pvts, tmppvt)) {
+		if (tmppvt && !ao2_link(info->new_array[obj->pvt_index], tmppvt)) {
 			ast_log(LOG_ERROR, "In %s: Linking private for %s failed\n", info->filename, cat);
 			return -1;
 		}
-		if (!ao2_link(obj->new_cfgs, tmpcfg)) {
+		if (!ao2_link(info->new_array[obj->cfg_index], tmpcfg)) {
 			ast_log(LOG_ERROR, "In %s: Linking config for %s failed\n", info->filename, cat);
 			return -1;
 		}
 	}
+	return 0;
+}
+
+static int apply_config(struct aco_info *info)
+{
+	size_t x;
+
+	__ao2_global_obj_wrlock(info->current_array);
+	for (x = 0; x < info->current_array->num_elements; x++) {
+		__ao2_global_obj_replace_unref(info->current_array, x, info->new_array[x], 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, "bob");
+	}
+	__ao2_global_obj_unlock(info->current_array);
+
 	return 0;
 }
 
@@ -418,7 +404,7 @@
 		return -1;
 	}
 
-	ao2_callback(info->objs, OBJ_NODATA, allocate_temp_objects, &err);
+	ao2_callback_data(info->types, OBJ_NODATA, allocate_temp_objects, info, &err);
 
 	if (err) {
 		ast_log(LOG_ERROR, "In %s: Could not allocate temporary objects\n", info->filename);
@@ -442,14 +428,14 @@
 
 	ast_config_destroy(cfg);
 
-	res = info->apply_config(); /* The module already knows where the objects are */
-	ao2_callback(info->objs, OBJ_NODATA, cleanup_temp_objects, NULL);
+	res = apply_config(info); /* The module already knows where the objects are */
+	ao2_callback(info->types, OBJ_NODATA, cleanup_temp_objects, info);
 
 	return res;
 
 error:
 	ast_config_destroy(cfg);
-	ao2_callback(info->objs, OBJ_NODATA, cleanup_temp_objects, NULL);
+	ao2_callback(info->types, OBJ_NODATA, cleanup_temp_objects, info);
 	return -1;
 }
 
@@ -482,11 +468,18 @@
 	if (!(info->opts = aco_option_container_alloc())) {
 		return -1;
 	}
-	if (!(info->objs = aco_type_container_alloc())) {
+	if (!(info->types = aco_type_container_alloc())) {
 		ao2_ref(info->opts, -1);
 		info->opts = NULL;
 		return -1;
 	}
+	if (!(info->new_array = ast_calloc(info->current_array->num_elements, sizeof(info->new_array)))) {
+		ao2_ref(info->opts, -1);
+		info->opts = NULL;
+		ao2_ref(info->types, -1);
+		info->types = NULL;
+		return -1;
+	}
 	return 0;
 }
 
@@ -495,9 +488,10 @@
 	if (info->opts) {
 		ao2_ref(info->opts, -1);
 	}
-	if (info->objs) {
-		ao2_ref(info->objs, -1);
-	}
+	if (info->types) {
+		ao2_ref(info->types, -1);
+	}
+	ast_free(info->new_array);
 }
 
 /*! \brief match for anything where the category passes (or fails if !category_allow) the category regex
@@ -532,7 +526,7 @@
 		}
 		if (opt->handler(opt, var, obj)) {
 			ao2_ref(opt, -1);
-			ast_log(LOG_NOTICE, "Unable to set default for %s, %s=%s\n", category, var->name, var->value);
+			ast_log(LOG_ERROR, "Unable to set default for %s, %s=%s\n", category, var->name, var->value);
 			return -1;
 		}
 		ao2_ref(opt, -1);
@@ -570,7 +564,7 @@
 	return;
 }
 
-struct aco_type *aco_type_global_alloc(const char *name, enum aco_category_op op, const char *category, aco_type_alloc alloc)
+struct aco_type *aco_type_global_alloc(const char *name, size_t global_index, enum aco_category_op op, const char *category, aco_type_alloc alloc)
 {
 	struct aco_type *obj;
 
@@ -585,6 +579,7 @@
 
 	obj->type = GLOBAL_OBJ;
 	obj->name = name;
+	obj->global_index = global_index;
 	obj->category_allow = op;
 	obj->cfg_alloc = alloc;
 	obj->category = category;
@@ -592,7 +587,22 @@
 	return obj;
 }
 
-struct aco_type *aco_type_private_alloc(const char *name, enum aco_category_op op, const char *category, const char *matchfield, const char *matchvalue,
+struct aco_type *aco_type_object(struct aco_type *type)
+{
+	struct aco_type *obj;
+
+	if (!(obj = ao2_alloc(sizeof(*obj), config_obj_destructor))) {
+		return NULL;
+	}
+	*obj = *type;
+	if (!(obj->regex = build_category_regex(obj->category))) {
+		ao2_ref(obj, -1);
+		return NULL;
+	}
+	return obj;
+}
+
+struct aco_type *aco_type_private_alloc(const char *name, size_t pvt_index, size_t cfg_index, enum aco_category_op op, const char *category, const char *matchfield, const char *matchvalue,
 	aco_type_alloc alloc, aco_type_containers_alloc containers_alloc, aco_type_find_or_create_pvt find_or_create_pvt,
 	aco_type_find_pvt find_pvt, aco_type_post_cfg_init post_cfg_init, aco_type_prelink prelink)
 {
@@ -609,6 +619,8 @@
 
 	obj->type = PRIVATE_OBJ;
 	obj->name = name;
+	obj->pvt_index = pvt_index;
+	obj->cfg_index = cfg_index;
 	obj->category_allow = op;
 	obj->cfg_alloc = alloc;
 	obj->category = category;
@@ -625,18 +637,18 @@
 
 int aco_type_register(struct aco_info *info, struct aco_type *obj)
 {
-	if (!info->objs) {
-		return -1;
-	}
-	return !ao2_link(info->objs, obj);
+	if (!info->types) {
+		return -1;
+	}
+	return !ao2_link(info->types, obj);
 }
 
 struct aco_type *aco_type_find(struct aco_info *info, const char *name)
 {
-	if (!info->objs) {
-		return NULL;
-	}
-	return ao2_find(info->objs, name, OBJ_KEY);
+	if (!info->types) {
+		return NULL;
+	}
+	return ao2_find(info->types, name, OBJ_KEY);
 }
 
 void *aco_info_new_global_get(struct aco_info *info, const char *name)
@@ -645,10 +657,10 @@
 	if (!type) {
 		return NULL;
 	}
-	if (type->new_global_cfg) {
-		ao2_ref(type->new_global_cfg, +1);
-	}
-	return type->new_global_cfg;
+	if (info->new_array[type->global_index]) {
+		ao2_ref(info->new_array[type->global_index], +1);
+	}
+	return info->new_array[type->global_index];
 }
 
 struct ao2_container *aco_info_new_privates_get(struct aco_info *info, const char *name)
@@ -657,10 +669,10 @@
 	if (!type) {
 		return NULL;
 	}
-	if (type->new_pvts) {
-		ao2_ref(type->new_pvts, +1);
-	}
-	return type->new_pvts;
+	if (info->new_array[type->pvt_index]) {
+		ao2_ref(info->new_array[type->pvt_index], +1);
+	}
+	return info->new_array[type->pvt_index];
 }
 
 struct ao2_container *aco_info_new_configs_get(struct aco_info *info, const char *name)
@@ -669,10 +681,10 @@
 	if (!type) {
 		return NULL;
 	}
-	if (type->new_cfgs) {
-		ao2_ref(type->new_cfgs, +1);
-	}
-	return type->new_cfgs;
+	if (info->new_array[type->cfg_index]) {
+		ao2_ref(info->new_array[type->cfg_index], +1);
+	}
+	return info->new_array[type->cfg_index];
 }
 
 /* default config option handlers */

Modified: team/twilson/config_work/main/udptl.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/udptl.c?view=diff&rev=366047&r1=366046&r2=366047
==============================================================================
--- team/twilson/config_work/main/udptl.c (original)
+++ team/twilson/config_work/main/udptl.c Thu May 10 10:27:57 2012
@@ -186,23 +186,22 @@
 	unsigned int use_even_ports;
 };
 
-AST_MUTEX_DEFINE_STATIC(reload_lock);
-
 static int udptl_apply_config(void);
+
+enum {
+	UDPTL_GENERAL = 0,
+
+	/* Must be last */
+	UDPTL_NUM_GLOBALS,
+} global_opt_type;
+
+static AO2_GLOBAL_OBJ_STATIC(globals, UDPTL_NUM_GLOBALS);
 
 CONFIG_INFO_STANDARD(cfg_info,
 	.filename = "udptl.conf",
 	.apply_config = udptl_apply_config,
+	.current_array = &globals.global,
 );
-
-enum {
-	UDPTL_GENERAL = 0,
-
-	/* Must be last */
-	UDPTL_NUM_GLOBALS,
-} global_opt_type;
-
-static AO2_GLOBAL_OBJ_STATIC(globals, UDPTL_NUM_GLOBALS);
 
 static inline int udptl_debug_test_addr(const struct ast_sockaddr *addr)
 {
@@ -1394,11 +1393,9 @@
 
 static void __ast_udptl_reload(int reload)
 {
-	ast_mutex_lock(&reload_lock);
 	if (aco_process_config(&cfg_info, reload)) {
 		ast_log(LOG_WARNING, "Could not reload udptl config\n");
 	}
-	ast_mutex_unlock(&reload_lock);
 }
 
 static int udptl_apply_config(void) {
@@ -1454,7 +1451,7 @@
 		return;
 	}
 
-	if (!(global_type = aco_type_global_alloc("global", ACO_WHITELIST, "general", udptl_cfg_alloc))) {
+	if (!(global_type = aco_type_global_alloc("global", UDPTL_GENERAL, ACO_WHITELIST, "general", udptl_cfg_alloc))) {
 		aco_info_destroy(&cfg_info);
 		return;
 	}




More information about the asterisk-commits mailing list