From 5f50f76b6685c4952d2b4083cabb8ed765729ca0 Mon Sep 17 00:00:00 2001 From: "Antonio S. Musumeci" Date: Fri, 10 Apr 2026 22:18:23 -0400 Subject: [PATCH] fix idle self-exit allowing pool to drain to 0 threads _remove_thread_scaling_locked floors min_allowed at 1, preventing remove_thread/set_threads from ever reducing the pool below 1 thread. But start_routine_autoscale passed raw _scaling_config.min_threads to _try_remove_self_if_above without the same floor. With min_threads == 0, all idle workers could self-exit, draining the pool to zero threads and permanently stalling any work enqueued via non-autoscale enqueue_work (which doesn't call _maybe_grow_on_pressure). Apply the same max(min_threads, 1) floor in start_routine_autoscale to keep the two shrink paths consistent. Co-Authored-By: Claude Opus 4.6 (1M context) --- vendored/libfuse/include/thread_pool.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vendored/libfuse/include/thread_pool.hpp b/vendored/libfuse/include/thread_pool.hpp index 3d9e753a..6bda4be1 100644 --- a/vendored/libfuse/include/thread_pool.hpp +++ b/vendored/libfuse/include/thread_pool.hpp @@ -514,7 +514,12 @@ ThreadPool::start_routine_autoscale(void *arg_) // // name was already copied into a local at function entry, // so the syslog below is also safe. - std::size_t const min_thr = btp->_scaling_config.min_threads; + // Floor at 1 to match _remove_thread_scaling_locked's + // min_allowed floor. Without this, min_threads == 0 + // would let all workers self-exit, draining the pool + // to zero threads and stalling non-autoscale enqueues. + std::size_t const min_thr = std::max(btp->_scaling_config.min_threads, + (std::size_t)1); if(btp->_try_remove_self_if_above(pthread_self(),min_thr)) { syslog(LOG_DEBUG,