aboutsummaryrefslogtreecommitdiff
path: root/src/lib/pubsub/pubsub_build.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-01-15 10:46:01 -0500
committerNick Mathewson <nickm@torproject.org>2019-03-25 16:35:33 -0400
commita7681525ab670c2b7a783f9e1285bf9a8e97d1ea (patch)
tree52e35ff7af6efc0599de9815465610d5351f0341 /src/lib/pubsub/pubsub_build.c
parent271a67182211a954dba1082739f8fe7daf421f6c (diff)
downloadtor-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.c30
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);