Skip to content

Commit a4c158d

Browse files
ThomasBradyedsiper
authored andcommitted
thread_storage: Use pthread_once to ensure FLB_TLS_INIT only calls pthread_key_create once for each key
This patch ensures pthread_key_create is only called once per TLS key by using pthread_once for thread-safe idempotent initialization. This prevents race conditions and errors when FLB_TLS_INIT is called from multiple locations (different compilation units, hot reloads, etc). Changes: - Modified FLB_TLS_INIT macro to use pthread_once control structure - Updated FLB_TLS_DEFINE to include pthread_once_t and init function - Added FLB_TLS_DECLARE macro for external TLS key declarations - Updated flb_log.h, flb_output.h, and flb_scheduler.h to use new FLB_TLS_DECLARE for proper extern declarations The implementation wraps pthread_key_create in a function called via pthread_once, guaranteeing single initialization regardless of how many times FLB_TLS_INIT is invoked. Signed-off-by: Thomas Brady <thomas.brady@chronosphere.io>
1 parent cddd506 commit a4c158d

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

include/fluent-bit/flb_log.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
#include <stdarg.h>
3636

3737
/* FIXME: this extern should be auto-populated from flb_thread_storage.h */
38-
extern FLB_TLS_DEFINE(struct flb_log, flb_log_ctx)
38+
#ifndef FLB_HAVE_C_TLS
39+
FLB_TLS_DECLARE(struct flb_log, flb_log_ctx);
40+
#else
41+
extern FLB_TLS_DEFINE(struct flb_log, flb_log_ctx);
42+
#endif
3943

4044
/* Message types */
4145
#define FLB_LOG_OFF 0

include/fluent-bit/flb_output.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,11 @@ struct flb_out_flush_params {
593593
struct flb_coro *coro; /* coroutine context */
594594
};
595595

596+
#ifndef FLB_HAVE_C_TLS
597+
FLB_TLS_DECLARE(struct flb_out_flush_params, out_flush_params);
598+
#else
596599
extern FLB_TLS_DEFINE(struct flb_out_flush_params, out_flush_params);
600+
#endif
597601

598602
#define FLB_OUTPUT_RETURN(x) \
599603
flb_output_return_do(x); \

include/fluent-bit/flb_scheduler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,11 @@ struct flb_sched_timer_coro_cb_params {
203203
struct flb_coro *coro;
204204
};
205205

206+
#ifndef FLB_HAVE_C_TLS
207+
FLB_TLS_DECLARE(struct flb_sched_timer_coro_cb_params, sched_timer_coro_cb_params);
208+
#else
206209
extern FLB_TLS_DEFINE(struct flb_sched_timer_coro_cb_params, sched_timer_coro_cb_params);
210+
#endif
207211

208212

209213
struct flb_timer_cb_coro_params {

include/fluent-bit/flb_thread_storage.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,41 @@
4040
/* Fallback mode using pthread_*() for Thread-Local-Storage usage */
4141
#define FLB_TLS_SET(key, val) pthread_setspecific(key, (void *) val)
4242
#define FLB_TLS_GET(key) pthread_getspecific(key)
43-
#define FLB_TLS_INIT(key) pthread_key_create(&key, NULL)
44-
#define FLB_TLS_DEFINE(type, name) pthread_key_t name;
43+
44+
/*
45+
* Thread-safe idempotent initialization using pthread_once.
46+
* This ensures pthread_key_create is only called once even if FLB_TLS_INIT
47+
* is called from multiple locations (different compilation units, hot reload, etc).
48+
*/
49+
#define FLB_TLS_INIT(key) \
50+
do { \
51+
extern pthread_once_t key##_once; \
52+
void key##_init_func(void); \
53+
pthread_once(&key##_once, key##_init_func); \
54+
} while(0)
55+
56+
/* Define a TLS key with its pthread_once control and init function */
57+
#define FLB_TLS_DEFINE(type, name) \
58+
pthread_key_t name; \
59+
pthread_once_t name##_once = PTHREAD_ONCE_INIT; \
60+
void name##_init_func(void) { \
61+
pthread_key_create(&name, NULL); \
62+
}
63+
64+
/* Declare a TLS key that's defined elsewhere */
65+
#define FLB_TLS_DECLARE(type, name) \
66+
extern pthread_key_t name; \
67+
extern pthread_once_t name##_once; \
68+
void name##_init_func(void);
4569
#endif
4670

4771

4872
/* FIXME: this extern should be auto-populated from flb_thread_storage.h */
49-
extern FLB_TLS_DEFINE(struct flb_worker, flb_worker_ctx)
73+
#ifndef FLB_HAVE_C_TLS
74+
FLB_TLS_DECLARE(struct flb_worker, flb_worker_ctx);
75+
#else
76+
extern FLB_TLS_DEFINE(struct flb_worker, flb_worker_ctx);
77+
#endif
5078

5179

5280
#endif /* !FLB_THREAD_STORAGE_H */

0 commit comments

Comments
 (0)