Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/fluent-bit/flb_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
#include <stdarg.h>

/* 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
Expand Down
4 changes: 4 additions & 0 deletions include/fluent-bit/flb_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
Expand Down
4 changes: 4 additions & 0 deletions include/fluent-bit/flb_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
34 changes: 31 additions & 3 deletions include/fluent-bit/flb_thread_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
}
Comment on lines +57 to +62
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle pthread_key_create failure to avoid undefined TLS state.

With the new pthread_once wrapper we only invoke pthread_key_create() once. If that call returns an error (e.g. EAGAIN, ENOMEM), the key stays uninitialized but the pthread_once guard prevents any retry, so every later FLB_TLS_SET/GET will operate on an invalid key and the failure is silent. Before this change we at least retried on the next FLB_TLS_INIT, so this is a regression in resiliency. Please capture the return code, surface/log it, and keep the caller from proceeding (e.g. by storing the status in a companion variable that FLB_TLS_INIT checks and aborts or reports). That way we fail fast instead of running with a broken TLS slot.

🤖 Prompt for AI Agents
In include/fluent-bit/flb_thread_storage.h around lines 57 to 62, the
pthread_key_create() result is ignored so if it fails the pthread_once guard
prevents retries and TLS key remains uninitialized; modify the macro to capture
the return code from pthread_key_create into a companion int status variable
(e.g. name##_init_rc), set it atomically, and have
FLB_TLS_INIT/FLB_TLS_GET/FLB_TLS_SET check that status and abort/log/return an
error when non-zero; also log the errno/rc when pthread_key_create fails to
surface the root cause and avoid proceeding with an invalid key.


/* 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 */
Loading