From: Arran Cudbard-Bell Date: Wed, 31 Mar 2021 12:42:06 +0000 (+0100) Subject: Add function to explicitly trigger all thread local destructors X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=110ee29db5be95f8f8a93aa30f97180dbb9d3b25;p=thirdparty%2Ffreeradius-server.git Add function to explicitly trigger all thread local destructors --- diff --git a/src/lib/eap_aka_sim/base.c b/src/lib/eap_aka_sim/base.c index 41a16489146..4377b523444 100644 --- a/src/lib/eap_aka_sim/base.c +++ b/src/lib/eap_aka_sim/base.c @@ -40,6 +40,8 @@ RCSID("$Id$") #include #include +#include "crypto_priv.h" + static uint32_t instance_count = 0; fr_dict_t const *dict_freeradius; @@ -279,6 +281,8 @@ void fr_aka_sim_free(void) if (--instance_count > 0) return; fr_dict_autofree(libfreeradius_aka_sim_dict); + + fr_thread_local_atexit_trigger(_evp_cipher_ctx_free_on_exit); } static fr_table_num_ordered_t const subtype_table[] = { diff --git a/src/lib/eap_aka_sim/crypto.c b/src/lib/eap_aka_sim/crypto.c index f36dd3be385..8350d85c95e 100644 --- a/src/lib/eap_aka_sim/crypto.c +++ b/src/lib/eap_aka_sim/crypto.c @@ -55,7 +55,7 @@ RCSID("$Id$") */ static _Thread_local EVP_CIPHER_CTX *evp_chipher_ctx; -static void _evp_cipher_ctx_free_on_exit(void *arg) +void _evp_cipher_ctx_free_on_exit(void *arg) { EVP_CIPHER_CTX_free(arg); } diff --git a/src/lib/eap_aka_sim/crypto_priv.h b/src/lib/eap_aka_sim/crypto_priv.h index 488fba52ded..8644c277354 100644 --- a/src/lib/eap_aka_sim/crypto_priv.h +++ b/src/lib/eap_aka_sim/crypto_priv.h @@ -28,6 +28,8 @@ extern "C" { #endif +void _evp_cipher_ctx_free_on_exit(void *arg); /* Used as a handle to disable destructors on fr_aka_sim_free */ + EVP_CIPHER_CTX *aka_sim_crypto_cipher_ctx(void); #ifdef __cplusplus diff --git a/src/lib/util/thread_local.c b/src/lib/util/thread_local.c index 4346ff3363b..b9143324cd8 100644 --- a/src/lib/util/thread_local.c +++ b/src/lib/util/thread_local.c @@ -313,3 +313,36 @@ void fr_thread_local_atexit_disarm_all(void) } } +/** Iterates through all thread local destructor lists, causing destructor to be triggered + * + * This should only be called by the main process, and not by threads. + * + * @param[in] func Entries matching this function will be triggered. + * @return How many triggers fired. + */ +int fr_thread_local_atexit_trigger(fr_thread_local_atexit_t func) +{ + fr_exit_handler_entry_t *e = NULL, *ee; + fr_exit_handler_list_t *list; + unsigned int count = 0; + + if (global_atexit) return 0; + + /* + * Iterate over the list of thread local destructor + * lists. + */ + while ((e = fr_dlist_next(&global_atexit->head, e))) { + if (!e->func) continue; /* thread already joined */ + + list = talloc_get_type_abort(e->uctx, fr_exit_handler_list_t); + while ((ee = fr_dlist_next(&list->head, ee))) { + if (ee->func != func) continue; + + count++; + ee = fr_dlist_talloc_free_item(&list->head, ee); + } + } + + return count; +} diff --git a/src/lib/util/thread_local.h b/src/lib/util/thread_local.h index 37253bcbb95..2a3da1e01b6 100644 --- a/src/lib/util/thread_local.h +++ b/src/lib/util/thread_local.h @@ -65,6 +65,8 @@ do { \ _n = _v; \ } while (0); +int fr_thread_local_atexit_trigger(fr_thread_local_atexit_t func); + #ifdef __cplusplus } #endif