diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-01-15 10:46:01 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-03-25 16:35:33 -0400 |
commit | a7681525ab670c2b7a783f9e1285bf9a8e97d1ea (patch) | |
tree | 52e35ff7af6efc0599de9815465610d5351f0341 /src/lib/pubsub/pubsub_build.c | |
parent | 271a67182211a954dba1082739f8fe7daf421f6c (diff) | |
download | tor-a7681525ab670c2b7a783f9e1285bf9a8e97d1ea.tar.gz tor-a7681525ab670c2b7a783f9e1285bf9a8e97d1ea.zip |
Add function to clear publish bindings.
When we clean up, we'd like to clear all the bindings that refer to
a dispatch_t, so that they don't have dangling pointers to it.
Diffstat (limited to 'src/lib/pubsub/pubsub_build.c')
-rw-r--r-- | src/lib/pubsub/pubsub_build.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/lib/pubsub/pubsub_build.c b/src/lib/pubsub/pubsub_build.c index 7e4ab5ba8f..64cdcc1d57 100644 --- a/src/lib/pubsub/pubsub_build.c +++ b/src/lib/pubsub/pubsub_build.c @@ -242,10 +242,10 @@ pubsub_connector_define_type_(pubsub_connector_t *con, * for <b>d</b>. */ static void -dispatch_fill_pub_binding_backptrs(pubsub_builder_t *builder, - dispatch_t *d) +pubsub_items_install_bindings(pubsub_items_t *items, + dispatch_t *d) { - SMARTLIST_FOREACH_BEGIN(builder->items->items, pubsub_cfg_t *, cfg) { + SMARTLIST_FOREACH_BEGIN(items->items, pubsub_cfg_t *, cfg) { if (cfg->pub_binding) { // XXXX we could skip this for STUB publishers, and for any publishers // XXXX where all subscribers are STUB. @@ -255,12 +255,28 @@ dispatch_fill_pub_binding_backptrs(pubsub_builder_t *builder, } /** + * Remove the dispatch_ptr fields for all the relevant publish bindings + * in <b>items</b>. The prevents subsequent dispatch_pub_() calls from + * sending messages to a dispatcher that has been freed. + **/ +void +pubsub_items_clear_bindings(pubsub_items_t *items) +{ + SMARTLIST_FOREACH_BEGIN(items->items, pubsub_cfg_t *, cfg) { + if (cfg->pub_binding) { + cfg->pub_binding->dispatch_ptr = NULL; + } + } SMARTLIST_FOREACH_END(cfg); +} + +/** * Create a new dispatcher as configured in a pubsub_builder_t. * * Consumes and frees its input. **/ dispatch_t * -pubsub_builder_finalize(pubsub_builder_t *builder) +pubsub_builder_finalize(pubsub_builder_t *builder, + pubsub_items_t **items_out) { dispatch_t *dispatcher = NULL; tor_assert_nonfatal(builder->n_connectors == 0); @@ -276,7 +292,11 @@ pubsub_builder_finalize(pubsub_builder_t *builder) if (!dispatcher) goto err; - dispatch_fill_pub_binding_backptrs(builder, dispatcher); + pubsub_items_install_bindings(builder->items, dispatcher); + if (items_out) { + *items_out = builder->items; + builder->items = NULL; /* Prevent free */ + } err: pubsub_builder_free(builder); |