[svn-commits] twilson: branch twilson/config_work r366464 - in /team/twilson/config_work: a...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon May 14 17:14:31 CDT 2012
Author: twilson
Date: Mon May 14 17:14:26 2012
New Revision: 366464
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=366464
Log:
Check in work to avoid race condition when querying config objects
Instead of storing and swapping out the config objects indivdually and
possibly getting a reload in between a request for a privates container
and the private config info container, store all of the config objects
in a single object that we swap out and get back. This object represents
a snapshot of all config data so that everything is 100% consistent.
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
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=366464&r1=366463&r2=366464
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Mon May 14 17:14:26 2012
@@ -130,47 +130,42 @@
size_t non_config_state;
};
-enum {
- GLOBAL_OPTIONS = 0,
- PVT_CFG_CONTAINER,
- PVT_CONTAINER,
-
- /* Must be declared last */
- NUM_GLOBAL_OBJECTS,
-};
-
#define PVT_BUCKETS 17
-static void *skel_global_alloc(const char *cat);
+struct skel_config {
+ struct skel_global_config *general;
+ struct ao2_container *pvts;
+ struct ao2_container *cfgs;
+};
+
+static void *skel_config_alloc(void);
static void *skel_pvt_cfg_alloc(const char *cat);
-static int skel_containers_alloc(struct ao2_container **newpvts, struct ao2_container **newcfgs);
static void *skel_find_or_create_pvt(const char *category);
static void *skel_find_pvt(struct ao2_container *tmp_container, const char *category);
static struct aco_type general_options = {
.type = ACO_GLOBAL_OBJ,
- .global_index = GLOBAL_OPTIONS,
+ .cfg_offset = offsetof(struct skel_config, general),
.category_allow = ACO_WHITELIST,
.category = "general",
- .cfg_alloc = skel_global_alloc,
};
static struct aco_type private_options = {
.type = ACO_PRIVATE_OBJ,
- .pvt_index = PVT_CONTAINER,
- .cfg_index = PVT_CFG_CONTAINER,
.category_allow = ACO_BLACKLIST,
.category = "general",
.cfg_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 AO2_GLOBAL_OBJ_STATIC(globals, NUM_GLOBAL_OBJECTS);
+ .pvt_offset = offsetof(struct skel_config, pvts),
+ .cfg_offset = offsetof(struct skel_config, cfgs),
+};
+
+static AO2_GLOBAL_OBJ_STATIC(globals, 1);
CONFIG_INFO_STANDARD(cfg_info, "app_skel.conf", globals,
.types = { &general_options, &private_options, NULL },
+ .snapshot_alloc = skel_config_alloc,
);
static void skel_global_config_destructor(void *obj)
@@ -179,19 +174,19 @@
ast_string_field_free_memory(cfg);
}
-static void skel_pvt_cfg_unlink(struct skel_pvt_config *cfg)
-{
- RAII_VAR(struct ao2_container *, cfgs, ao2_global_obj_ref(globals, PVT_CFG_CONTAINER), ao2_cleanup);
- if (cfgs) {
- ao2_unlink(cfgs, cfg);
+static void skel_pvt_cfg_unlink(struct skel_pvt_config *pcfg)
+{
+ RAII_VAR(struct skel_config *, cfg, ao2_global_obj_ref(globals, 0), ao2_cleanup);
+ if (cfg && cfg->cfgs) {
+ ao2_unlink(cfg->cfgs, pcfg);
}
}
static struct skel_pvt_config *skel_pvt_find_cfg(struct skel_pvt *pvt)
{
- RAII_VAR(struct ao2_container *, cfgs, ao2_global_obj_ref(globals, PVT_CFG_CONTAINER), ao2_cleanup);
- if (cfgs) {
- return ao2_find(cfgs, pvt->name, OBJ_KEY);
+ RAII_VAR(struct skel_config *, cfg, ao2_global_obj_ref(globals, 0), ao2_cleanup);
+ if (cfg && cfg->cfgs) {
+ return ao2_find(cfg->cfgs, pvt->name, OBJ_KEY);
}
return NULL;
@@ -239,19 +234,6 @@
struct skel_pvt_config *one = obj, *two = arg;
const char *match = (flags & OBJ_KEY) ? arg : two->name;
return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
-}
-
-static int skel_containers_alloc(struct ao2_container **newpvts, struct ao2_container **newcfgs)
-{
- if (!(*newpvts = ao2_container_alloc(PVT_BUCKETS, skel_pvt_hash, skel_pvt_cmp))) {
- return -1;
- }
- if (!(*newcfgs = ao2_container_alloc(PVT_BUCKETS, skel_pvt_config_hash, skel_pvt_config_cmp))) {
- ao2_ref(*newpvts, -1);
- *newpvts = NULL;
- return -1;
- }
- return 0;
}
/*! \brief A custom bitfield handler
@@ -341,9 +323,9 @@
static void *skel_find_or_create_pvt(const char *category)
{
- RAII_VAR(struct ao2_container *, pvt_container, ao2_global_obj_ref(globals, PVT_CONTAINER), ao2_cleanup);
+ RAII_VAR(struct skel_config *, cfg, ao2_global_obj_ref(globals, 0), ao2_cleanup);
void *obj;
- if (!pvt_container || !(obj = ao2_find(pvt_container, category, OBJ_KEY))) {
+ if (!cfg || !cfg->pvts || !(obj = ao2_find(cfg->pvts, category, OBJ_KEY))) {
return skel_pvt_alloc(category);
}
return obj;
@@ -372,30 +354,48 @@
return pvtcfg;
}
-static void *skel_global_alloc(const char *cat)
-{
- struct skel_global_config *cfg;
-
- if (cat) {
+static void skel_config_destructor(void *obj)
+{
+ struct skel_config *cfg = obj;
+ ao2_cleanup(cfg->general);
+ ao2_cleanup(cfg->pvts);
+ ao2_cleanup(cfg->cfgs);
+}
+
+static void *skel_config_alloc(void)
+{
+ struct skel_config *cfg;
+
+ if (!(cfg = ao2_alloc(sizeof(*cfg), skel_config_destructor))) {
return NULL;
}
/* Allocate/initialize memory */
- if (!(cfg = ao2_alloc(sizeof(*cfg), skel_global_config_destructor))) {
- return NULL;
- }
-
- if (ast_string_field_init(cfg, 128)) {
- ao2_ref(cfg, -1);
- return NULL;
+ if (!(cfg->general = ao2_alloc(sizeof(*cfg->general), skel_global_config_destructor))) {
+ goto error;
+ }
+
+ if (ast_string_field_init(cfg->general, 128)) {
+ goto error;
+ }
+
+ if (!(cfg->pvts = ao2_container_alloc(PVT_BUCKETS, skel_pvt_hash, skel_pvt_cmp))) {
+ goto error;
+ }
+
+ if (!(cfg->cfgs = ao2_container_alloc(PVT_BUCKETS, skel_pvt_config_hash, skel_pvt_config_cmp))) {
+ goto error;
}
return cfg;
+error:
+ ao2_ref(cfg, -1);
+ return NULL;
}
static char *handle_skel_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- RAII_VAR(struct skel_global_config *, cfg, NULL, ao2_cleanup);
+ RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
switch(cmd) {
case CLI_INIT:
@@ -408,23 +408,22 @@
return NULL;
}
- if (!(cfg = ao2_global_obj_ref(globals, GLOBAL_OPTIONS))) {
- return NULL;
- }
-
- ast_cli(a->fd, "foo: %s\n", cfg->foo);
- ast_cli(a->fd, "bar: %s\n", cfg->bar);
- ast_cli(a->fd, "baz: %s\n", cfg->baz);
- ast_cli(a->fd, "blah: %s\n", AST_CLI_YESNO(cfg->blah));
- ast_cli(a->fd, "bindaddr: %s\n", ast_sockaddr_stringify(&cfg->bindaddr));
+ if (!(cfg = ao2_global_obj_ref(globals, 0)) || !cfg->general) {
+ return NULL;
+ }
+
+ ast_cli(a->fd, "foo: %s\n", cfg->general->foo);
+ ast_cli(a->fd, "bar: %s\n", cfg->general->bar);
+ ast_cli(a->fd, "baz: %s\n", cfg->general->baz);
+ ast_cli(a->fd, "blah: %s\n", AST_CLI_YESNO(cfg->general->blah));
+ ast_cli(a->fd, "bindaddr: %s\n", ast_sockaddr_stringify(&cfg->general->bindaddr));
return CLI_SUCCESS;
}
static char *handle_skel_show_pvts(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- RAII_VAR(struct ao2_container *, pvts, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, cfgs, NULL, ao2_cleanup);
+ RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
struct ao2_iterator iter;
struct skel_pvt *pvt;
char codec_buf[128];
@@ -440,29 +439,25 @@
return NULL;
}
- if (!(pvts = ao2_global_obj_ref(globals, PVT_CONTAINER))) {
- return NULL;
- }
- if (!(cfgs = ao2_global_obj_ref(globals, PVT_CFG_CONTAINER))) {
- ao2_ref(pvts, -1);
+ if (!(cfg = ao2_global_obj_ref(globals, 0)) || !(cfg->cfgs && cfg->pvts)) {
return NULL;
}
#define SKEL_FORMAT "%-15.15s %-25.25s %-20.20s %-5.5s %-5.5s %-5.5s %-2.2s\n"
#define SKEL_FORMAT1 "%-15.15s %-25.25s %-20.20s %-5.5s %-5.5s %-5.5s %-2.2zu\n"
ast_cli(a->fd, SKEL_FORMAT, "Name", "Description", "Codecs", "ACL", "Bit1", "Bit2", "N");
- iter = ao2_iterator_init(pvts, 0);
+ iter = ao2_iterator_init(cfg->pvts, 0);
while ((pvt = ao2_iterator_next(&iter))) {
- RAII_VAR(struct skel_pvt_config *, cfg, NULL, ao2_cleanup);
- if (!(cfg = ao2_find(cfgs, pvt->name, OBJ_KEY))) {
+ RAII_VAR(struct skel_pvt_config *, pcfg, NULL, ao2_cleanup);
+ if (!(pcfg = ao2_find(cfg->cfgs, pvt->name, OBJ_KEY))) {
ast_log(LOG_NOTICE, "Could not find config info for %s\n", pvt->name);
ao2_ref(pvt, -1);
continue;
}
/* As an example of non-config-related state remaining between reloads */
++pvt->non_config_state;
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, cfg->caps);
- ast_cli(a->fd, SKEL_FORMAT1, pvt->name, cfg->description, codec_buf, AST_CLI_YESNO(cfg->permit != NULL), AST_CLI_YESNO(cfg->bit1), AST_CLI_YESNO(cfg->bit2), pvt->non_config_state);
+ ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, pcfg->caps);
+ ast_cli(a->fd, SKEL_FORMAT1, pvt->name, pcfg->description, codec_buf, AST_CLI_YESNO(pcfg->permit != NULL), AST_CLI_YESNO(pcfg->bit1), AST_CLI_YESNO(pcfg->bit2), pvt->non_config_state);
ao2_ref(pvt, -1);
}
ao2_iterator_destroy(&iter);
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=366464&r1=366463&r2=366464
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Mon May 14 17:14:26 2012
@@ -115,9 +115,8 @@
const char *matchvalue; /*!< The value of the option to require for matching (i.e. 'peer' for type= in sip.conf) */
regex_t *regex;
enum aco_category_op category_allow; /*!< Whether the following category regex is a whitelist or blacklist */
- size_t global_index; /*!< The index in the global object array for the global config */
- size_t pvt_index; /*!< The index in the global object array for the private container */
- size_t cfg_index; /*!< The index in the global object array for the private config container */
+ size_t cfg_offset; /*!< The offset in the config snapshot for the global config or private config container */
+ size_t pvt_offset; /*!< The index in the global object array for the private container */
aco_type_alloc cfg_alloc; /*!< An allocation function for ao2 object associated with this type */
/* non-global callbacks */
@@ -134,13 +133,20 @@
*/
typedef int (*aco_pre_apply_config)(void);
+/*! \brief A callback functino for allocating an object to hold all config objects
+ * \retval NULL error
+ * \retval non-NULL a config object container
+ */
+typedef void *(*aco_snapshot_alloc)(void);
+
struct aco_info {
const char *module; /*!< The name of the module whose config is being processed */
const char *filename; /*!< The config filename */
struct ao2_container *opts; /*!< Internal use - options to parse */
aco_pre_apply_config pre_apply_config; /*!< A callback called after processing, but before changes are applied */
- struct ao2_global_obj *current_array; /*!< The module's global object array for this config */
- void **new_array; /*!< Internal use - A cache of new config objects to be applied */
+ aco_snapshot_alloc snapshot_alloc; /*!< Allocate an object to hold all global configs and private containers */
+ void *global_obj; /*!< The global object array that hold the config object */
+ void *new_config; /*!< Internal use - A cache of newly created config */
const char **preload; /*!< Categories to parse first. Do something like char *arr[] = {"general", NULL}; and do .preload = arr */
struct aco_type *types[]; /*!< The list of types for this config. Required. Use a sentinel! */
};
@@ -166,7 +172,7 @@
static struct aco_info name = { \
.module = AST_MODULE, \
.filename = fn, \
- .current_array = &arr.global, \
+ .global_obj = &arr.global, \
__VA_ARGS__ \
};
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=366464&r1=366463&r2=366464
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Mon May 14 17:14:26 2012
@@ -180,55 +180,6 @@
return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp);
}
-static int allocate_temp_objects(struct aco_info *info)
-{
- struct aco_type *t;
- size_t x;
-
- for (x = 0, t = info->types[x]; t; t = info->types[++x]) {
- switch (t->type) {
- case ACO_GLOBAL_OBJ:
- if (!(info->new_array[t->global_index] = t->cfg_alloc(NULL))) {
- return -1;
- }
- break;
- case ACO_PRIVATE_OBJ:
- if (t->containers_alloc((struct ao2_container **) &info->new_array[t->pvt_index], (struct ao2_container **) &info->new_array[t->cfg_index])) {
- return -1;
- }
- break;
- }
- }
- return 0;
-}
-
-static void cleanup_temp_objects(struct aco_info *info)
-{
- struct aco_type *t;
- size_t x;
-
- for (x = 0, t = info->types[x]; t; t = info->types[++x]) {
- switch (t->type) {
- case ACO_GLOBAL_OBJ:
- 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 ACO_PRIVATE_OBJ:
- 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;
- }
- }
-}
-
static struct aco_type *internal_aco_type_find(struct aco_info *info, struct ast_config *cfg, const char *category)
{
size_t x;
@@ -291,19 +242,21 @@
}
/* if type == GLOBAL_OBJ, set defaults and configure the cached cfg object */
- if (obj->type == ACO_GLOBAL_OBJ && info->new_array[obj->global_index]) {
- if (aco_set_defaults(info->opts, cat, info->new_array[obj->global_index])) {
+ if (obj->type == ACO_GLOBAL_OBJ && info->new_config + obj->cfg_offset) {
+ void **pretend = info->new_config + obj->cfg_offset;
+ if (aco_set_defaults(info->opts, cat, *pretend)) {
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, info->new_array[obj->global_index])) {
+ if (aco_process_category_options(info->opts, cfg, cat, *pretend)) {
ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", info->filename, cat);
return -1;
}
} else if (obj->type == ACO_PRIVATE_OBJ) {
+ void **pretend = info->new_config + obj->pvt_offset;
/* If we've already linked a private for cat in newpvts, don't add a second one with the same name */
- if (info->new_array[obj->pvt_index]) {
- if ((tmppvt = obj->find_pvt(info->new_array[obj->pvt_index], cat))) {
+ if (*pretend) {
+ if ((tmppvt = obj->find_pvt(*pretend, cat))) {
ast_log(LOG_ERROR, "In %s: Multiple definitions of %s!\n", info->filename, cat);
return -1;
}
@@ -343,11 +296,12 @@
}
/* We have a valid pvt/cfg, link 'em */
- if (tmppvt && !ao2_link(info->new_array[obj->pvt_index], tmppvt)) {
+ if (tmppvt && !ao2_link(*pretend, tmppvt)) {
ast_log(LOG_ERROR, "In %s: Linking private for %s failed\n", info->filename, cat);
return -1;
}
- if (!ao2_link(info->new_array[obj->cfg_index], tmpcfg)) {
+ pretend = info->new_config + obj->cfg_offset;
+ if (!ao2_link(*pretend, tmpcfg)) {
ast_log(LOG_ERROR, "In %s: Linking config for %s failed\n", info->filename, cat);
return -1;
}
@@ -357,13 +311,7 @@
static int apply_config(struct aco_info *info)
{
- size_t x;
-
- __ao2_global_obj_wrlock(info->current_array, __FILE__, __LINE__, __PRETTY_FUNCTION__, "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__, "unused");
- }
- __ao2_global_obj_unlock(info->current_array, __FILE__, __LINE__, __PRETTY_FUNCTION__, "info->current_array");
+ __ao2_global_obj_replace_unref(info->global_obj, 0, info->new_config, 1, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, "info->global_obj");
return 0;
}
@@ -394,7 +342,7 @@
return -1;
}
- if (allocate_temp_objects(info)) {
+ if (!(info->new_config = info->snapshot_alloc())) {
ast_log(LOG_ERROR, "In %s: Could not allocate temporary objects\n", info->filename);
goto error;
}
@@ -421,13 +369,13 @@
}
res = apply_config(info); /* The module already knows where the objects are */
- cleanup_temp_objects(info);
+ ao2_ref(info->new_config, -1);
return res;
error:
ast_config_destroy(cfg);
- cleanup_temp_objects(info);
+ ao2_ref(info->new_config, -1);
return -1;
}
@@ -499,11 +447,6 @@
}
}
- if (!(info->new_array = ast_calloc(info->current_array->num_elements, sizeof(info->new_array)))) {
- ao2_ref(info->opts, -1);
- info->opts = NULL;
- return -1;
- }
return 0;
}
@@ -513,7 +456,6 @@
ao2_ref(info->opts, -1);
}
internal_info_types_destroy(info);
- ast_free(info->new_array);
}
/*! \brief match for anything where the category passes (or fails if !category_allow) the category regex
@@ -629,7 +571,7 @@
return ast_parse_allow_disallow(pref, *cap, var->value, opt->flags);
}
-/* opt->args[0] = ast_string_field, opt->args[1] = field_mgr_pool, opt->args[2] = field_mgri */
+/* opt->args[0] = ast_string_field, opt->args[1] = field_mgr_pool, opt->args[2] = field_mgr */
int ast_config_option_stringfield_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
ast_string_field *field = (const char **)(obj + opt->args[0]);
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=366464&r1=366463&r2=366464
==============================================================================
--- team/twilson/config_work/main/udptl.c (original)
+++ team/twilson/config_work/main/udptl.c Mon May 14 17:14:26 2012
@@ -195,19 +195,22 @@
static AO2_GLOBAL_OBJ_STATIC(globals, UDPTL_NUM_GLOBALS);
-static void *udptl_cfg_alloc(const char *unused);
+struct udptl_config {
+ struct udptl_global_options *general;
+};
+
+static void *udptl_snapshot_alloc(void);
static int udptl_pre_apply_config(void);
static struct aco_type general_options = {
.type = ACO_GLOBAL_OBJ,
- .global_index = UDPTL_GENERAL,
.category_allow = ACO_WHITELIST,
.category = "general",
- .cfg_alloc = udptl_cfg_alloc,
};
CONFIG_INFO_STANDARD(cfg_info, "udptl.conf", globals,
.types = { &general_options, NULL },
+ .snapshot_alloc = udptl_snapshot_alloc,
.pre_apply_config = udptl_pre_apply_config,
);
@@ -951,9 +954,9 @@
int startplace;
int i;
long int flags;
- RAII_VAR(struct udptl_global_options *, opts, ao2_global_obj_ref(globals, UDPTL_GENERAL), ao2_cleanup);
-
- if (!opts) {
+ RAII_VAR(struct udptl_config *, cfg, ao2_global_obj_ref(globals, 0), ao2_cleanup);
+
+ if (!cfg || !cfg->general) {
ast_log(LOG_ERROR, "Could not access global udptl options!\n");
return NULL;
}
@@ -962,8 +965,8 @@
return NULL;
}
- udptl->error_correction_span = opts->fecspan;
- udptl->error_correction_entries = opts->fecentries;
+ udptl->error_correction_span = cfg->general->fecspan;
+ udptl->error_correction_entries = cfg->general->fecentries;
udptl->far_max_datagram = -1;
udptl->far_max_ifp = -1;
@@ -985,13 +988,13 @@
fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
#ifdef SO_NO_CHECK
- if (opts->nochecksums)
- setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &opts->nochecksums, sizeof(opts->nochecksums));
+ if (cfg->general->nochecksums)
+ setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &cfg->general->nochecksums, sizeof(cfg->general->nochecksums));
#endif
/* Find us a place */
- x = (opts->start == opts->end) ? opts->start : (ast_random() % (opts->end - opts->start)) + opts->start;
- if (opts->use_even_ports && (x & 1)) {
+ x = (cfg->general->start == cfg->general->end) ? cfg->general->start : (ast_random() % (cfg->general->end - cfg->general->start)) + cfg->general->start;
+ if (cfg->general->use_even_ports && (x & 1)) {
++x;
}
startplace = x;
@@ -1007,13 +1010,13 @@
ast_free(udptl);
return NULL;
}
- if (opts->use_even_ports) {
+ if (cfg->general->use_even_ports) {
x += 2;
} else {
++x;
}
- if (x > opts->end)
- x = opts->start;
+ if (x > cfg->general->end)
+ x = cfg->general->start;
if (x == startplace) {
ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
close(udptl->fd);
@@ -1344,7 +1347,7 @@
static char *handle_cli_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- RAII_VAR(struct udptl_global_options *, opts, NULL, ao2_cleanup);
+ RAII_VAR(struct udptl_config *, cfg, NULL, ao2_cleanup);
switch (cmd) {
case CLI_INIT:
@@ -1357,18 +1360,18 @@
return NULL;
}
- if (!(opts = ao2_global_obj_ref(globals, UDPTL_GENERAL))) {
+ if (!(cfg = ao2_global_obj_ref(globals, 0))) {
return CLI_FAILURE;
}
ast_cli(a->fd, "UDPTL Global options\n");
ast_cli(a->fd, "--------------------\n");
- ast_cli(a->fd, "udptlstart: %u\n", opts->start);
- ast_cli(a->fd, "udptlend: %u\n", opts->end);
- ast_cli(a->fd, "udptlfecentries: %u\n", opts->fecentries);
- ast_cli(a->fd, "udptlfecspan: %u\n", opts->fecspan);
- ast_cli(a->fd, "use_even_ports: %s\n", AST_CLI_YESNO(opts->use_even_ports));
- ast_cli(a->fd, "udptlchecksums: %s\n", AST_CLI_YESNO(!opts->nochecksums));
+ ast_cli(a->fd, "udptlstart: %u\n", cfg->general->start);
+ ast_cli(a->fd, "udptlend: %u\n", cfg->general->end);
+ ast_cli(a->fd, "udptlfecentries: %u\n", cfg->general->fecentries);
+ ast_cli(a->fd, "udptlfecspan: %u\n", cfg->general->fecspan);
+ ast_cli(a->fd, "use_even_ports: %s\n", AST_CLI_YESNO(cfg->general->use_even_ports));
+ ast_cli(a->fd, "udptlchecksums: %s\n", AST_CLI_YESNO(!cfg->general->nochecksums));
return CLI_SUCCESS;
}
@@ -1378,15 +1381,25 @@
AST_CLI_DEFINE(handle_cli_show_config, "Show UDPTL config options"),
};
-static void *udptl_cfg_alloc(const char *unused)
-{
- struct udptl_global_options *opts;
-
- if (!(opts = ao2_alloc(sizeof(*opts), NULL))) {
+static void udptl_config_destructor(void *obj)
+{
+ struct udptl_config *cfg = obj;
+ ao2_cleanup(cfg->general);
+}
+
+static void *udptl_snapshot_alloc(void)
+{
+ struct udptl_config *cfg;
+
+ if (!(cfg = ao2_alloc(sizeof(*cfg), udptl_config_destructor))) {
return NULL;
}
-
- return opts;
+ if (!(cfg->general = ao2_alloc(sizeof(*cfg->general), NULL))) {
+ ao2_ref(cfg, -1);
+ return NULL;
+ }
+
+ return cfg;
}
static int removed_options_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
@@ -1407,7 +1420,8 @@
}
static int udptl_pre_apply_config(void) {
- struct udptl_global_options * new_global = cfg_info.new_array[UDPTL_GENERAL];
+ struct udptl_config *cfg = cfg_info.new_config;
+ struct udptl_global_options *new_global = cfg->general;
if (!new_global) {
return -1;
@@ -1435,13 +1449,6 @@
ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_even_ports enabled. udptlend is now %d\n", new_global->end);
}
- /* Replace existing config */
- if (ao2_global_obj_replace_unref(globals, UDPTL_GENERAL, new_global)) {
- ast_verb(2, "UDPTL allocating from port range %d -> %d via reload\n", new_global->start, new_global->end);
- } else {
- ast_verb(2, "UDPTL allocating from port range %d -> %d via intial load\n", new_global->start, new_global->end);
- }
-
return 0;
}
More information about the svn-commits
mailing list