diff --git a/include/fluent-bit/flb_log.h b/include/fluent-bit/flb_log.h index 75de5060984..90f145efff8 100644 --- a/include/fluent-bit/flb_log.h +++ b/include/fluent-bit/flb_log.h @@ -35,7 +35,11 @@ #include /* FIXME: this extern should be auto-populated from flb_thread_storage.h */ -extern FLB_TLS_DEFINE(struct flb_log, flb_log_ctx) +#ifndef FLB_HAVE_C_TLS +FLB_TLS_DECLARE(struct flb_log, flb_log_ctx); +#else +extern FLB_TLS_DEFINE(struct flb_log, flb_log_ctx); +#endif /* Message types */ #define FLB_LOG_OFF 0 diff --git a/include/fluent-bit/flb_output.h b/include/fluent-bit/flb_output.h index d9675e48bc4..7cd3a9628f1 100644 --- a/include/fluent-bit/flb_output.h +++ b/include/fluent-bit/flb_output.h @@ -592,7 +592,11 @@ struct flb_out_flush_params { struct flb_coro *coro; /* coroutine context */ }; +#ifndef FLB_HAVE_C_TLS +FLB_TLS_DECLARE(struct flb_out_flush_params, out_flush_params); +#else extern FLB_TLS_DEFINE(struct flb_out_flush_params, out_flush_params); +#endif #define FLB_OUTPUT_RETURN(x) \ flb_output_return_do(x); \ diff --git a/include/fluent-bit/flb_scheduler.h b/include/fluent-bit/flb_scheduler.h index 11b526d350f..f5ecc042310 100644 --- a/include/fluent-bit/flb_scheduler.h +++ b/include/fluent-bit/flb_scheduler.h @@ -200,7 +200,11 @@ struct flb_sched_timer_coro_cb_params { struct flb_coro *coro; }; +#ifndef FLB_HAVE_C_TLS +FLB_TLS_DECLARE(struct flb_sched_timer_coro_cb_params, sched_timer_coro_cb_params); +#else extern FLB_TLS_DEFINE(struct flb_sched_timer_coro_cb_params, sched_timer_coro_cb_params); +#endif struct flb_timer_cb_coro_params { diff --git a/include/fluent-bit/flb_thread_storage.h b/include/fluent-bit/flb_thread_storage.h index 7ec9df94010..a442929f96f 100644 --- a/include/fluent-bit/flb_thread_storage.h +++ b/include/fluent-bit/flb_thread_storage.h @@ -40,13 +40,41 @@ /* Fallback mode using pthread_*() for Thread-Local-Storage usage */ #define FLB_TLS_SET(key, val) pthread_setspecific(key, (void *) val) #define FLB_TLS_GET(key) pthread_getspecific(key) -#define FLB_TLS_INIT(key) pthread_key_create(&key, NULL) -#define FLB_TLS_DEFINE(type, name) pthread_key_t name; + +/* + * Thread-safe idempotent initialization using pthread_once. + * This ensures pthread_key_create is only called once even if FLB_TLS_INIT + * is called from multiple locations (different compilation units, hot reload, etc). + */ +#define FLB_TLS_INIT(key) \ + do { \ + extern pthread_once_t key##_once; \ + void key##_init_func(void); \ + pthread_once(&key##_once, key##_init_func); \ + } while(0) + +/* Define a TLS key with its pthread_once control and init function */ +#define FLB_TLS_DEFINE(type, name) \ + pthread_key_t name; \ + pthread_once_t name##_once = PTHREAD_ONCE_INIT; \ + void name##_init_func(void) { \ + pthread_key_create(&name, NULL); \ + } + +/* Declare a TLS key that's defined elsewhere */ +#define FLB_TLS_DECLARE(type, name) \ + extern pthread_key_t name; \ + extern pthread_once_t name##_once; \ + void name##_init_func(void); #endif /* FIXME: this extern should be auto-populated from flb_thread_storage.h */ -extern FLB_TLS_DEFINE(struct flb_worker, flb_worker_ctx) +#ifndef FLB_HAVE_C_TLS +FLB_TLS_DECLARE(struct flb_worker, flb_worker_ctx); +#else +extern FLB_TLS_DEFINE(struct flb_worker, flb_worker_ctx); +#endif #endif /* !FLB_THREAD_STORAGE_H */