From: Arran Cudbard-Bell Date: Thu, 3 Mar 2022 00:04:20 +0000 (-0600) Subject: Call detach on shallowest parent first X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2682bb8ce955d05490375e9347e5240f353e003b;p=thirdparty%2Ffreeradius-server.git Call detach on shallowest parent first --- diff --git a/src/lib/server/dl_module.c b/src/lib/server/dl_module.c index 4f8db617463..5b5bb3314ac 100644 --- a/src/lib/server/dl_module.c +++ b/src/lib/server/dl_module.c @@ -247,18 +247,38 @@ void *dl_module_parent_data_by_child_data(void const *data) return dl_inst->parent->data; } +/** Detach the shallowest parent first + * + */ +static void dl_module_detach_parent(dl_module_inst_t *dl_inst) +{ + if (dl_inst->detached) return; + + if (dl_inst->parent) dl_module_detach_parent(UNCONST(dl_module_inst_t *, dl_inst->parent)); + + if (dl_inst->module->common->detach) { + dl_inst->module->common->detach(&(module_detach_ctx_t){ .inst = dl_inst }); + dl_inst->detached = true; + } +} + static int _dl_module_instance_data_free(void *data) { - dl_module_inst_t const *dl_inst = dl_module_instance_by_data(data); + dl_module_inst_t *dl_inst = UNCONST(dl_module_inst_t *, dl_module_instance_by_data(data)); - if (!dl_inst) { - ERROR("Failed resolving data %p, to dl_module_inst_t, refusing to free", data); - return -1; - } + if (!dl_inst) { + ERROR("Failed resolving data %p, to dl_module_inst_t, refusing to free", data); + return -1; + } - if (dl_inst->module->common->detach) dl_inst->module->common->detach(&(module_detach_ctx_t){ .inst = dl_inst }); + /* + * Ensure the shallowest parent module + * gets detached first so that it can + * still reach its children. + */ + dl_module_detach_parent(dl_inst); - return 0; + return 0; } /** Allocate module instance data, and parse the module's configuration diff --git a/src/lib/server/dl_module.h b/src/lib/server/dl_module.h index c67ecaa8015..1849bf050c4 100644 --- a/src/lib/server/dl_module.h +++ b/src/lib/server/dl_module.h @@ -164,6 +164,7 @@ struct dl_module_instance_s { void * _CONST data; //!< Module instance's parsed configuration. CONF_SECTION * _CONST conf; //!< Module's instance configuration. dl_module_inst_t const * _CONST parent; //!< Parent module's instance (if any). + bool _CONST detached; //!< Whether the detach function has been called. }; extern fr_table_num_sorted_t const dl_module_type_prefix[];