|
40 | 40 | /* Fallback mode using pthread_*() for Thread-Local-Storage usage */ |
41 | 41 | #define FLB_TLS_SET(key, val) pthread_setspecific(key, (void *) val) |
42 | 42 | #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); |
45 | 69 | #endif |
46 | 70 |
|
47 | 71 |
|
48 | 72 | /* 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 |
50 | 78 |
|
51 | 79 |
|
52 | 80 | #endif /* !FLB_THREAD_STORAGE_H */ |
0 commit comments