std::thread::LocalKeyState: Add fourth Initializing state #43491
Labels
C-feature-request
Category: A feature request, i.e: not implemented / a PR.
T-libs-api
Relevant to the library API team, which will review and decide on the PR/issue.
Right now,
LocalKeyState
contains three states:Uninitialized
,Valid
, andDestroyed
.Unfortunately, this is not enough to cover all cases. In particular, consider the following code (adapted from some code I wrote as part of writing a global allocator - to motivate that this is a real-world example):
The idea here is to ensure that the local key hasn't yet been destroyed - and if it has, to fall back on some global state instead. If the key is valid, then obviously this is fine. If the key is uninitialized, then
with
should perform initialization, which should also be fine...unless
local_or_global
is called from the initialization routine. This is the case for the allocator code I'm working on since initializing TLS requires performing allocations. In that case, you end up with infinite recursion and eventually a stack overflow.My proposal is the following: add a fourth
Initializing
state. Whenwith
is first called and the key needs to be initialized, it is first moved into theInitializing
state. When initialization completes, it is subsequently moved into theValid
state. This allows code that accesses the key to detect whether it's being called from inside the initializer, and behave appropriately in that case (in particular, by not accessing the key and thus recursing the initialization).The concrete issue I (along with my collaborator on this project, @ezrosent) have run into is that initializing TLS depends on allocation, which depends on TLS, which depends on... In general, this is a problem whenever a TLS key's initialization routine transitively depends on itself (either directly, or through an arbitrarily long cycle of other TLS key dependencies - for example, we've seen similar issues with
Destroyed
keys when using Crossbeam's epoch-based memory reclamation, which also uses TLS under the hood).Alternatives
It might be tempting to think that just making sure you're in the
Valid
state is a sufficient (if sub-optimal) solution to this problem (and in fact, I thought the same thing for a while). Unfortunately, this solves a chicken-and-egg problem by just deciding that chickens can't exist. By only being willing to access a TLS key in theValid
state, you preclude ever calling code that will perform initialization, and thus you'll never move to theValid
state in the first place.The text was updated successfully, but these errors were encountered: