Skip to content

Reset pooled LocalAllocator when attaching a thread - #1435

Open
Simn wants to merge 1 commit into
masterfrom
fix-pooled-allocator-race
Open

Simn wants to merge 1 commit into
masterfrom
fix-pooled-allocator-race

Conversation

@Simn

@Simn Simn commented Oct 28, 2026

Copy link
Copy Markdown
Member

When a thread registers, RegisterCurrentThread takes a LocalAllocator from the pool in GetPooledAllocator, which holds gThreadStateChangeLock only for that step. AttachThread then calls AddLocal, which takes the lock again. In between, the allocator is neither in the pool nor in mLocalAllocs.

A collection resets every registered allocator at the end of Mark and every pooled one in ClearPooledAlloc. An allocator caught in that window gets neither reset. It keeps its holes, the collection may reclaim those blocks for other allocations, and the newly attached thread then allocates over live objects.

The fix calls Reset() at the start of AttachThread. That only drops the allocator's current holes, so the thread starts with a fresh allocation region.

This is easy to hit when threads attach and detach very often. hxcpp_luv_io's Work.queue registers the libuv worker thread with SetTopOfStack(&top, true) and unregisters it with UnregisterCurrentThread() for every work item. hxcoro's LuvDispatcher sends every dispatch through Work.queue. With that dispatcher, about 25% of hxcoro's C++ test runs on Windows crashed with access violations in unrelated objects (6 of 30). With this change, there were no access violations in 60 runs.

🤖 Generated with Claude Code

Between GetPooledAllocator and AddLocal, the allocator is neither pooled nor
registered, so a collection in that window does not reset it. The thread then
allocates from holes that the collection may have handed out again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant