You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Collected ThreadLocal owners can leave their values rooted on long-lived threads #181
The fix for #68 prevents a recycled ThreadLocal slot from returning its previous owner's value, but the old value can still stay alive indefinitely on a long-lived thread.
In src/hx/thread/ThreadLocal.cpp, Impl::finalise increments the slot generation and returns the Impl to the free list. It does not clear the values stored on threads.
In src/hx/thread/ThreadImpl.cpp:
getLocal clears a stale value only when that slot is read with a different generation.
setLocal clears it by overwriting the slot when the replacement owner writes on that same thread.
__Mark marks the whole localSlots array without checking whether each slot still has a live owner.
If a ThreadLocal is collected and the thread never accesses its recycled slot again, that thread's ThreadImpl keeps marking the old value and everything reachable from it. Reusing the slot on some other thread does not clear this thread's value either. This can retain large request-local or task-local graphs in persistent workers.
This is a source-level retention finding, not a measured leak reproduction. A regression should establish that the ThreadLocal owner itself has been collected, then check a weak reference to its former payload after further collections while the worker remains alive. Keep the payload off conservative stacks and do not read or overwrite the slot, since either would hide the problem.
The generation check should also allow stale values to stop being GC roots without requiring another access on that thread. Possible approaches include a GC-aware slot-owner registry or clearing dead-owner slots while mutators are stopped. Account for finalizer ordering, surviving ThreadLocals, generational barriers and slot reuse before choosing an approach. Do not mutate a running thread's Haxe arrays from the ThreadLocal finalizer without synchronization.
This follows up on the retention part of #68. Its existing regression checks that reads return null for a recycled slot; it does not check that an unaccessed stale payload becomes collectible.
Activity
Release values of collected ThreadLocals