mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
_remove_thread_scaling_locked increments _remove_count to signal a worker to self-exit, but this counter is only checked after a worker completes a real task. Workers blocked on wait_dequeue (standard loop) or try_wait_dequeue_for (autoscale loop) never see the removal request, so shrinking an idle pool via remove_thread() or set_threads() stalls indefinitely. Fix: enqueue a wakeup poison pill alongside each _remove_count increment so a blocked worker is guaranteed to wake up. To prevent double-removal (one worker exits via the task-completion CAS loop consuming _remove_count, another exits via the wakeup pill), the poison pill handler now attempts to consume a _remove_count before self-removing. If the count is already zero (claimed by a worker that finished a real task), the pill is treated as stale and the worker continues processing. Shutdown path is unaffected: the destructor sets _stop before enqueueing its own pills, and the pill handler checks _stop first, returning BREAK unconditionally during shutdown regardless of _remove_count. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| moodycamel | ||
| base_types.h | ||
| bounded_queue.hpp | ||
| debug.hpp | ||
| extern_c.h | ||
| fatal.hpp | ||
| fs_dirent64.hpp | ||
| fuse.h | ||
| fuse_attr.h | ||
| fuse_cfg.hpp | ||
| fuse_common.h | ||
| fuse_conn_info.hpp | ||
| fuse_dirent.h | ||
| fuse_direntplus.h | ||
| fuse_dirents.hpp | ||
| fuse_entry.h | ||
| fuse_kernel.h | ||
| fuse_lowlevel.h | ||
| fuse_msgbuf.hpp | ||
| fuse_msgbuf_t.h | ||
| fuse_opt.h | ||
| fuse_pollhandle.h | ||
| fuse_req.hpp | ||
| fuse_req_ctx.h | ||
| fuse_timeouts.h | ||
| invocable.h | ||
| kvec.h | ||
| maintenance_thread.hpp | ||
| mutex.hpp | ||
| mutex_debug.hpp | ||
| mutex_ndebug.hpp | ||
| objpool.hpp | ||
| stat_utils.h | ||
| syslog.hpp | ||
| thread_pool.hpp | ||