Document why relaxed ordering is correct for _remove_count CAS

The CAS loop on _remove_count uses memory_order_relaxed for both
success and failure, which is correct but non-obvious.  Add a comment
explaining that _remove_self acquires _threads_mutex immediately after
the successful CAS, and that mutex acquisition provides the necessary
happens-before edge between the scaling-side increment and the
worker-side erase/detach.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Antonio S. Musumeci
2026-04-10 13:41:06 -04:00
co-authored by Claude Opus 4.6
parent 02703ef239
commit 65e136c667
+6
View File
@@ -416,6 +416,12 @@ ThreadPool::_process_func(Func &func_)
// Workers race to claim a decrement after each task; the winner
// detaches itself and exits. During shutdown (_stop set),
// _remove_self is a no-op, so the destructor still joins us.
//
// Relaxed ordering is sufficient here: the only side-effect of
// claiming the decrement is _remove_self, which acquires
// _threads_mutex. That mutex provides the necessary happens-
// before relationship between the increment (scaling side) and
// the erase/detach (worker side).
{
std::size_t count = _remove_count.load(std::memory_order_relaxed);
while(count > 0)