[tor-commits] [tor/master] Partial support for multiplicity in configuration objects
dgoulet at torproject.org
dgoulet at torproject.org
Wed Sep 4 14:39:08 UTC 2019
commit 638e58379a4c5347dd4952f12dd3b1054e7bb19f
Author: Nick Mathewson <nickm at torproject.org>
Date: Wed Jul 24 11:20:55 2019 -0400
Partial support for multiplicity in configuration objects
A configuration manager, in addition to a top-level format object,
may now also know about a suite of sub-formats. Top-level
configuration objects, in turn, may now have a suite of
sub-objects.
---
src/app/config/confparse.c | 105 +++++++++++++++++++++++++++++++++++++--------
src/app/config/confparse.h | 2 +
2 files changed, 90 insertions(+), 17 deletions(-)
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index d94a1d9ec..8018f6a6d 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -73,10 +73,10 @@ managed_var_free_(managed_var_t *mv)
FREE_AND_NULL(managed_var_t, managed_var_free_, (mv))
struct config_suite_t {
- /* NOTE: This object isn't implemented yet; it's just a placeholder
- * to make sure we have our memory menagement right.
- */
- int foo;
+ /** A list of configuration objects managed by a given configuration
+ * manager. They are stored in the same order as the config_format_t
+ * objects in the manager's list of subformats. */
+ smartlist_t *configs;
};
/**
@@ -86,6 +86,7 @@ static config_suite_t *
config_suite_new(void)
{
config_suite_t *suite = tor_malloc_zero(sizeof(config_suite_t));
+ suite->configs = smartlist_new();
return suite;
}
@@ -96,6 +97,7 @@ config_suite_free_(config_suite_t *suite)
{
if (!suite)
return;
+ smartlist_free(suite->configs);
tor_free(suite);
}
@@ -110,6 +112,11 @@ struct config_mgr_t {
* contains. A subsequent commit will add more. XXXX)
*/
const config_format_t *toplevel;
+ /**
+ * List of second-level configuration format objects that this manager
+ * also knows about.
+ */
+ smartlist_t *subconfigs;
/** A smartlist of managed_var_t objects for all configuration formats. */
smartlist_t *all_vars;
/** A smartlist of config_abbrev_t objects for all abbreviations. These
@@ -137,12 +144,14 @@ config_mgr_t *
config_mgr_new(const config_format_t *toplevel_fmt)
{
config_mgr_t *mgr = tor_malloc_zero(sizeof(config_mgr_t));
- mgr->toplevel = toplevel_fmt;
+ mgr->subconfigs = smartlist_new();
mgr->all_vars = smartlist_new();
mgr->all_abbrevs = smartlist_new();
mgr->all_deprecations = smartlist_new();
config_mgr_register_fmt(mgr, toplevel_fmt, IDX_TOPLEVEL);
+ mgr->toplevel = toplevel_fmt;
+
return mgr;
}
@@ -158,6 +167,14 @@ config_mgr_register_fmt(config_mgr_t *mgr,
"Tried to add a format to a configuration manager after "
"it had been frozen.");
+ if (object_idx != IDX_TOPLEVEL) {
+ tor_assertf(fmt->config_suite_offset < 0,
+ "Tried to register a toplevel format in a non-toplevel position");
+ }
+ tor_assertf(fmt != mgr->toplevel &&
+ ! smartlist_contains(mgr->subconfigs, fmt),
+ "Tried to register an already-registered format.");
+
/* register variables */
for (i = 0; fmt->vars[i].member.name; ++i) {
managed_var_t *mv = tor_malloc_zero(sizeof(managed_var_t));
@@ -182,6 +199,21 @@ config_mgr_register_fmt(config_mgr_t *mgr,
}
}
+/**
+ * Add a new format to this configuration object. Asserts on failure.
+ *
+ **/
+int
+config_mgr_add_format(config_mgr_t *mgr,
+ const config_format_t *fmt)
+{
+ tor_assert(mgr);
+ int idx = smartlist_len(mgr->subconfigs);
+ config_mgr_register_fmt(mgr, fmt, idx);
+ smartlist_add(mgr->subconfigs, (void *)fmt);
+ return idx;
+}
+
/** Return a pointer to the config_suite_t * pointer inside a
* configuration object; returns NULL if there is no such member. */
static inline config_suite_t **
@@ -204,10 +236,19 @@ config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel)
static void *
config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
{
- (void)mgr;
- tor_assert(idx == IDX_TOPLEVEL); // nothing else is implemented yet XXXX
+ tor_assert(mgr);
tor_assert(toplevel);
- return toplevel;
+ if (idx == IDX_TOPLEVEL)
+ return toplevel;
+
+ tor_assertf(idx >= 0 && idx < smartlist_len(mgr->subconfigs),
+ "Index %d is out of range.", idx);
+ config_suite_t **suite = config_mgr_get_suite_ptr(mgr, toplevel);
+ tor_assert(suite);
+ tor_assert(smartlist_len(mgr->subconfigs) ==
+ smartlist_len((*suite)->configs));
+
+ return smartlist_get((*suite)->configs, idx);
}
/** As config_mgr_get_obj_mutable(), but return a const pointer. */
@@ -257,6 +298,7 @@ config_mgr_free_(config_mgr_t *mgr)
smartlist_free(mgr->all_vars);
smartlist_free(mgr->all_abbrevs);
smartlist_free(mgr->all_deprecations);
+ smartlist_free(mgr->subconfigs);
memset(mgr, 0, sizeof(*mgr));
tor_free(mgr);
}
@@ -296,6 +338,20 @@ config_mgr_assert_magic_ok(const config_mgr_t *mgr,
tor_assert(options);
tor_assert(mgr->frozen);
struct_check_magic(options, &mgr->toplevel_magic);
+
+ config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, (void*)options);
+ if (suitep == NULL) {
+ tor_assert(smartlist_len(mgr->subconfigs) == 0);
+ return;
+ }
+
+ tor_assert(smartlist_len((*suitep)->configs) ==
+ smartlist_len(mgr->subconfigs));
+ SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
+ void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
+ tor_assert(obj);
+ struct_check_magic(obj, &fmt->magic);
+ } SMARTLIST_FOREACH_END(fmt);
}
/** Macro: assert that <b>cfg</b> has the right magic field for
@@ -309,12 +365,16 @@ void *
config_new(const config_mgr_t *mgr)
{
tor_assert(mgr->frozen);
- const config_format_t *fmt = mgr->toplevel;
- void *opts = tor_malloc_zero(fmt->size);
+ void *opts = tor_malloc_zero(mgr->toplevel->size);
struct_set_magic(opts, &mgr->toplevel_magic);
config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, opts);
if (suitep) {
*suitep = config_suite_new();
+ SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
+ void *obj = tor_malloc_zero(fmt->size);
+ struct_set_magic(obj, &fmt->magic);
+ smartlist_add((*suitep)->configs, obj);
+ } SMARTLIST_FOREACH_END(fmt);
}
CONFIG_CHECK(mgr, opts);
return opts;
@@ -826,30 +886,41 @@ config_reset(const config_mgr_t *mgr, void *options,
void
config_free_(const config_mgr_t *mgr, void *options)
{
- const config_format_t *fmt = mgr->toplevel;
-
if (!options)
return;
- tor_assert(fmt);
+ tor_assert(mgr);
if (mgr->toplevel->clear_fn) {
mgr->toplevel->clear_fn(mgr, options);
}
+ config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, options);
+ if (suitep) {
+ tor_assert(smartlist_len((*suitep)->configs) ==
+ smartlist_len(mgr->subconfigs));
+ SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
+ void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
+ if (fmt->clear_fn) {
+ fmt->clear_fn(mgr, obj);
+ }
+ } SMARTLIST_FOREACH_END(fmt);
+ }
SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
config_clear(mgr, options, mv);
} SMARTLIST_FOREACH_END(mv);
- if (fmt->extra) {
- config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset);
+ if (mgr->toplevel->extra) {
+ config_line_t **linep = STRUCT_VAR_P(options,
+ mgr->toplevel->extra->offset);
config_free_lines(*linep);
*linep = NULL;
}
- config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, options);
- if (suitep)
+ if (suitep) {
+ SMARTLIST_FOREACH((*suitep)->configs, void *, obj, tor_free(obj));
config_suite_free(*suitep);
+ }
tor_free(options);
}
diff --git a/src/app/config/confparse.h b/src/app/config/confparse.h
index c18e85423..9125c0be3 100644
--- a/src/app/config/confparse.h
+++ b/src/app/config/confparse.h
@@ -76,6 +76,8 @@ typedef struct config_mgr_t config_mgr_t;
config_mgr_t *config_mgr_new(const config_format_t *toplevel_fmt);
void config_mgr_free_(config_mgr_t *mgr);
+int config_mgr_add_format(config_mgr_t *mgr,
+ const config_format_t *fmt);
void config_mgr_freeze(config_mgr_t *mgr);
#define config_mgr_free(mgr) \
FREE_AND_NULL(config_mgr_t, config_mgr_free_, (mgr))
More information about the tor-commits
mailing list