-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix: Make TLS initialization thread-safe and idempotent using pthread_once #11090
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix: Make TLS initialization thread-safe and idempotent using pthread_once #11090
Conversation
WalkthroughRefactored thread-local storage (TLS) initialization across Fluent Bit by introducing conditional macro patterns and idempotent initialization using Changes
Sequence Diagram(s)sequenceDiagram
participant Init as Initialization Code
participant Once as pthread_once
participant Key as TLS Key
participant InitFunc as Init Function
rect rgb(200, 220, 240)
Note over Init,InitFunc: Old: Direct initialization (unsafe race)
Init->>Key: Direct pthread_key_create()
end
rect rgb(240, 200, 220)
Note over Init,InitFunc: New: pthread_once pattern (thread-safe)
Init->>Once: Call FLB_TLS_INIT(key)
Once->>Once: pthread_once(&once_ctl, init_func)
Once->>InitFunc: Call init function (once)
InitFunc->>Key: pthread_key_create()
Once-->>Init: Return (subsequent calls are no-ops)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… once for each key Signed-off-by: Thomas Brady <[email protected]>
df31f5d to
289a534
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
include/fluent-bit/flb_log.h(1 hunks)include/fluent-bit/flb_output.h(1 hunks)include/fluent-bit/flb_scheduler.h(1 hunks)include/fluent-bit/flb_thread_storage.h(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
include/fluent-bit/flb_output.h (1)
src/flb_log.c (1)
FLB_TLS_DEFINE(50-56)
include/fluent-bit/flb_thread_storage.h (1)
src/flb_log.c (1)
FLB_TLS_DEFINE(50-56)
include/fluent-bit/flb_log.h (1)
src/flb_log.c (1)
FLB_TLS_DEFINE(50-56)
include/fluent-bit/flb_scheduler.h (1)
src/flb_log.c (1)
FLB_TLS_DEFINE(50-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (29)
- GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
- GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
- GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
- GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_ARROW=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
- GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
- GitHub Check: pr-compile-without-cxx (3.31.6)
- GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
- GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
- GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
- GitHub Check: pr-compile-centos-7
- GitHub Check: PR - fuzzing test
| #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); \ | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Upstreaming as requested by @cosmo0920.
Background:
flb_reload()callsflb_create()to create a new context for validation.flb_create()callsflb_log_create()which callsFLB_TLS_INIT(flb_worker_ctx). On platforms withoutFLB_HAVE_C_TLSdefined (e.g. Windows),FLB_TLS_INITdirectly callspthread_key_create.FLB_TLS_INITis also called from multiple other locations (flb_lib.c,flb_worker.c, etc.). Each call topthread_key_createwith the same key is undefined behavior per POSIX, causing issues like fluentbit logs not being output after a halted reload.Summary of changes
This patch makes FLB_TLS_INIT(key) idempotent using pthread_once:
Before: Each FLB_TLS_INIT call directly executed pthread_key_create, causing multiple key creations
After: Each FLB_TLS_INIT uses pthread_once to ensure the key is created exactly once, regardless of how many times or from where it's called
flb_log.h,flb_output.h,flb_scheduler.h) to use correct declaration patternThis ensures thread-safe, idempotent TLS initialization across all compilation units and during hot reload, eliminating the undefined behavior.
Enter
[N/A]in the box, if an item is not applicable to your change.Testing
Before we can approve your change; please submit the following in a comment:
If this is a change to packaging of containers or native binaries then please confirm it works for all targets.
ok-package-testlabel to test for all targets (requires maintainer to do).Documentation
Backporting
Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.
Summary by CodeRabbit