Repository navigation
fix(bthread): Destroy pooled KeyTables outside cache locks - #3682
Open
darion-yaphet wants to merge 1 commit into
Open
darion-yaphet wants to merge 1 commit into
darion-yaphet wants to merge 1 commit into
Conversation
Detach thread-local cached keytables while holding the pool and cache locks, then destroy them after releasing both locks. Add a regression test that checks the locks from the TLS destructor.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused cleanup change preserves shutdown synchronization and has targeted regression coverage, with no blocking issues identified.
No open issues 🎉
What changed in this PR
This PR addresses a bthread keytable-pool shutdown deadlock by moving TLS destructor execution outside cache-management locks, without changing public APIs.
Changes:
- Detach cached KeyTable chains under the locks, then destroy them after releasing both locks.
- Add a regression test that verifies TLS destructors can acquire both cache-management locks.
| File | Description |
|---|---|
test/bthread_key_unittest.cpp |
Adds regression coverage for lock availability during pooled TLS destruction. |
src/bthread/key.cpp |
Separates cache detachment from KeyTable destruction during pool shutdown. |
Review effort: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Destroying a
KeyTablemay run a user-provided TLS destructor. The destructor can wait for another bthread or access the same pool.Previously, pool destruction deleted cached KeyTables while holding both the pool write lock and
ThreadLocal's internal mutex. A user destructor could therefore wait for a bthread that needs one of these locks, causing a deadlock.The cleanup now works in two phases:
Summary
Pool destruction currently deletes cached KeyTables while holding both the pool write lock and
ThreadLocal's internal mutex. TLS destructors can execute user code, which may wait for or interact with tasks that need these locks.Detach KeyTable chains while the cache locks protect the pool structure, then destroy the detached KeyTables after releasing both locks. Delete the now-empty thread-local cache container afterward.
Add a regression test that attempts to acquire both locks from a TLS destructor. The test fails before the fix and verifies that both locks are available after it.
Testing
cmake --build build --target bthread_key_unittest -j6bthread_key_unittest --gtest_filter=KeyTest.*— 12 tests passed.KeyTest.pooled_destructor_runs_outside_cache_locksrepeated 30 times — passed.Risk and Rollback
The change preserves the pool shutdown sequence while moving user destructor execution outside cache-management locks. It does not change public APIs.