From fa4abbb6273d975b2ef17ac4e561fd4255d384db Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Tue, 19 Mar 2024 18:43:55 -0500 Subject: [PATCH] HG util: use destructor to free log outlets (fix #729) NA: fix missing free of dynamic plugin entries --- src/na/na.c | 2 ++ src/util/mercury_log.c | 49 ++++++++++++++++++------------------------ src/util/mercury_log.h | 20 +++++++++++++++-- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/na/na.c b/src/na/na.c index 78462f16..b7ca29dd 100644 --- a/src/na/na.c +++ b/src/na/na.c @@ -556,6 +556,8 @@ na_plugin_close_all(struct na_plugin_entry *entries) for (i = 0, entry = &entries[0]; entry->ops != NULL; i++, entry = &entries[i]) na_plugin_close(entry); + + free(entries); } /*---------------------------------------------------------------------------*/ diff --git a/src/util/mercury_log.c b/src/util/mercury_log.c index ad1b4c59..56ab3c0d 100644 --- a/src/util/mercury_log.c +++ b/src/util/mercury_log.c @@ -83,10 +83,6 @@ hg_log_init_subsys(bool level_set); static void hg_log_outlet_reset_all(void); -/* Free all attached logs */ -static void -hg_log_free_dlogs(void); - /* Is log active */ static int hg_log_outlet_active(const char *name); @@ -168,7 +164,8 @@ hg_log_init(void) static void hg_log_finalize(void) { - hg_log_free_dlogs(); + /* Deregister top outlet */ + hg_log_outlet_deregister(&HG_LOG_OUTLET(HG_LOG_OUTLET_ROOT_NAME)); } /*---------------------------------------------------------------------------*/ @@ -219,28 +216,6 @@ hg_log_outlet_reset_all(void) strcpy(hg_log_subsys_g[i], "\0"); } -/*---------------------------------------------------------------------------*/ -static void -hg_log_free_dlogs(void) -{ - struct hg_log_outlet *outlet; - - /* Free logs if any was attached */ - HG_QUEUE_FOREACH (outlet, &hg_log_outlets_g, entry) { - if (outlet->debug_log && - !(outlet->parent && outlet->parent->debug_log)) { - if (outlet->level >= HG_LOG_LEVEL_MIN_DEBUG) { - FILE *stream = hg_log_streams_g[outlet->level] - ? hg_log_streams_g[outlet->level] - : *hg_log_std_streams_g[outlet->level]; - hg_dlog_dump_counters( - outlet->debug_log, hg_log_func_g, stream, 0); - } - hg_dlog_free(outlet->debug_log); - } - } -} - /*---------------------------------------------------------------------------*/ static int hg_log_outlet_active(const char *name) @@ -495,7 +470,6 @@ hg_log_outlet_register(struct hg_log_outlet *hg_log_outlet) hg_log_init(); } #endif - hg_log_outlet_update_level(hg_log_outlet); /* Inherit debug log if not set and parent has one */ @@ -507,6 +481,25 @@ hg_log_outlet_register(struct hg_log_outlet *hg_log_outlet) hg_log_outlet->registered = true; } +/*---------------------------------------------------------------------------*/ +void +hg_log_outlet_deregister(struct hg_log_outlet *hg_log_outlet) +{ + if (hg_log_outlet->debug_log && + !(hg_log_outlet->parent && hg_log_outlet->parent->debug_log)) { + if (hg_log_outlet->level >= HG_LOG_LEVEL_MIN_DEBUG) { + FILE *stream = hg_log_streams_g[hg_log_outlet->level] + ? hg_log_streams_g[hg_log_outlet->level] + : *hg_log_std_streams_g[hg_log_outlet->level]; + hg_dlog_dump_counters( + hg_log_outlet->debug_log, hg_log_func_g, stream, 0); + } + hg_dlog_free(hg_log_outlet->debug_log); + } + HG_QUEUE_REMOVE(&hg_log_outlets_g, hg_log_outlet, hg_log_outlet, entry); + hg_log_outlet->registered = false; +} + /*---------------------------------------------------------------------------*/ void hg_log_write(struct hg_log_outlet *hg_log_outlet, enum hg_log_level log_level, diff --git a/src/util/mercury_log.h b/src/util/mercury_log.h index 24663ecc..b7624dad 100644 --- a/src/util/mercury_log.h +++ b/src/util/mercury_log.h @@ -38,6 +38,7 @@ /* Constructor (used to initialize log outlets) */ #define HG_UTIL_CONSTRUCTOR HG_ATTR_CONSTRUCTOR +#define HG_UTIL_DESTRUCTOR HG_ATTR_DESTRUCTOR /* Available log levels, additional log levels should be added to that list by * order of verbosity. Format is: @@ -92,11 +93,18 @@ /* HG_LOG_SUBSYS_REGISTER: register a name */ #define HG_LOG_SUBSYS_REGISTER(name) \ - static void HG_UTIL_CAT(hg_log_outlet_, name)(void) HG_UTIL_CONSTRUCTOR; \ - static void HG_UTIL_CAT(hg_log_outlet_, name)(void) \ + static void HG_UTIL_CAT(hg_log_outlet_reg_, name)(void) \ + HG_UTIL_CONSTRUCTOR; \ + static void HG_UTIL_CAT(hg_log_outlet_reg_, name)(void) \ { \ hg_log_outlet_register(&HG_LOG_OUTLET(name)); \ } \ + static void HG_UTIL_CAT(hg_log_outlet_dereg_, name)(void) \ + HG_UTIL_DESTRUCTOR; \ + static void HG_UTIL_CAT(hg_log_outlet_dereg_, name)(void) \ + { \ + hg_log_outlet_deregister(&HG_LOG_OUTLET(name)); \ + } \ /* Keep unused prototype to use semicolon at end of macro */ \ void hg_log_outlet_##name##_unused(void) @@ -385,6 +393,14 @@ hg_log_get_stream_debug(void); HG_UTIL_PUBLIC void hg_log_outlet_register(struct hg_log_outlet *outlet); +/** + * Deregister log outlet. + * + * \param outlet [IN] log outlet + */ +HG_UTIL_PUBLIC void +hg_log_outlet_deregister(struct hg_log_outlet *outlet); + /** * Write log. *