_try_remove_self_if_above only held _threads_mutex, while set_threads
and the monitor thread hold _scaling_mutex. An idle worker calling
_try_remove_self_if_above could shrink the pool concurrently with
set_threads reading _threads.size(), causing set_threads to
miscalculate the delta and overshoot (add too many or remove too few
threads).
Fix by acquiring _scaling_mutex before _threads_mutex in
_try_remove_self_if_above. This matches the existing lock ordering
used by _maybe_grow_on_pressure and the monitor/set_threads paths
(_scaling_mutex always acquired before _threads_mutex), so no
deadlock is introduced.
Now all paths that change the thread count — add_thread,
remove_thread, set_threads, monitor hill-climb, pressure grow, and
idle self-exit — are serialized under _scaling_mutex.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>