]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add function to explicitly trigger all thread local destructors
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 31 Mar 2021 12:42:06 +0000 (13:42 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 31 Mar 2021 15:12:53 +0000 (16:12 +0100)
src/lib/eap_aka_sim/base.c
src/lib/eap_aka_sim/crypto.c
src/lib/eap_aka_sim/crypto_priv.h
src/lib/util/thread_local.c
src/lib/util/thread_local.h

index 41a1648914671e2a9f1a2c31ff095de5ffc5644f..4377b52344459ccf5efdb1c03203a820251a1a77 100644 (file)
@@ -40,6 +40,8 @@ RCSID("$Id$")
 #include <freeradius-devel/eap_aka_sim/base.h>
 #include <freeradius-devel/eap_aka_sim/attrs.h>
 
+#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[] = {
index f36dd3be385333bd3888664b30969ea381482794..8350d85c95e80284fee39572a0b1308232b409b9 100644 (file)
@@ -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);
 }
index 488fba52ded7a96724ac9ed523b2f904c3f1183b..8644c277354e22f5366f67326f33cf68bd9af772 100644 (file)
@@ -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
index 4346ff3363b283433bb336a1cdd20dc897ea40a8..b9143324cd88836ee776263a9e156ea43490f73f 100644 (file)
@@ -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;
+}
index 37253bcbb959c26b30499217c6420bbc67953bc3..2a3da1e01b6a3d3a2127a09f97a6d7d980d978a7 100644 (file)
@@ -65,6 +65,8 @@ do { \
        _n = _v; \
 } while (0);
 
+int fr_thread_local_atexit_trigger(fr_thread_local_atexit_t func);
+
 #ifdef __cplusplus
 }
 #endif