27RCSIDH(atexit_h,
"$Id: 0a43d8a321f2cb51eef2a79e45a136a08974e52e $")
31#include <freeradius-devel/util/talloc.h>
58#define fr_atexit_global(_func, _uctx) _atexit_global(__FILE__, __LINE__, _func, _uctx)
78#ifdef TLS_STORAGE_CLASS
79# define _Thread_local TLS_STORAGE_CLASS
91 if (init_func)
if (init_func(uctx) < 0)
return -1;
102static inline int fr_atexit_talloc_free(
void *to_free)
130#define fr_atexit_global_once_ret(_ret, _init, _free, _uctx) \
132 static atomic_bool _init_done = false; \
133 static pthread_mutex_t _init_mutex = PTHREAD_MUTEX_INITIALIZER; \
134 void *_our_uctx = _uctx; \
136 if (unlikely(!atomic_load(&_init_done))) { \
137 pthread_mutex_lock(&_init_mutex); \
138 if (!atomic_load(&_init_done)) { \
139 if (_fr_atexit_global_once_funcs(_init, _free, _our_uctx) < 0) { \
142 atomic_store(&_init_done, true); \
144 pthread_mutex_unlock(&_init_mutex); \
169#define fr_atexit_global_once(_init, _free, _uctx) \
170 fr_atexit_global_once_ret(&(int){ 0 }, _init, _free, _uctx)
185# define fr_atexit_thread_local(_name, _free, _uctx) \
187 void *_our_uctx = _uctx; \
188 _fr_atexit_thread_local(__FILE__, __LINE__, _free, _our_uctx); \
192int _fr_atexit_thread_local(
char const *
file,
int line,
201bool fr_atexit_thread_is_exiting(
void);
213# define __Thread_local
214# define fr_atexit_global_once(_init, _free, _uctx) \
216 static bool _init_done = false; \
217 void * _our_uctx = _uctx; \
218 if (unlikely(!_init_done)) { \
220 fr_atexit_global(_free, _our_uctx); \
224# define fr_atexit_thread_local(_name, _free, _uctx) \
226 static bool _init_done = false; \
227 void * _our_uctx = _uctx; \
228 if (unlikely(!_init_done)) { \
229 fr_atexit_global(_free, _our_uctx); \
234# define fr_atexit_thread_local_disarm(...) fr_atexit_global_disarm(__VA_ARGS__)
235# define fr_atexit_thread_local_disarm_all(...) fr_atexit_global_disarm_all(__VA_ARGS__)
236# define fr_atexit_thread_trigger_all(...)
bool fr_atexit_thread_local_alloc_disabled(void)
Has fr_atexit_thread_local_disable_alloc been called yet.
int(* fr_atexit_t)(void *uctx)
Destructor callback.
void fr_atexit_thread_local_disable_alloc(void)
Disable lazy allocation of thread-local caches for the rest of the process.
unsigned int fr_atexit_global_disarm(bool uctx_scope, fr_atexit_t func, void const *uctx)
Remove a specific global destructor (without executing it)
#define fr_atexit_thread_trigger_all(...)
#define fr_atexit_thread_local_disarm(...)
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
void fr_atexit_global_disarm_all(void)
Remove all global destructors (without executing them)
#define fr_atexit_thread_local_disarm_all(...)
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
bool fr_atexit_is_exiting(void)
Return whether we're currently in the teardown phase.
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
int fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uctx)
Iterates through all thread local destructor lists, causing destructor to be triggered.
int _atexit_global(char const *file, int line, fr_atexit_t func, void const *uctx)
Add a free function to be called when the process exits.