From bd23a7b1794acfe1396e20a6db943b3501b66102 Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 10 Nov 2026 16:54:53 -0500 Subject: [PATCH] Keep the job queued when a dynamic worker thread cannot be created ThreadPool::enqueue constructed the dynamic thread without handling std::system_error. When thread creation failed (e.g. EAGAIN under a pids limit), the exception escaped the accept loop and destroying the pool's joinable threads called std::terminate. Treat the failure as "no spare capacity" and leave the job for an existing worker. --- httplib.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index 8ba0917e..b37b24b1 100644 --- a/httplib.h +++ b/httplib.h @@ -12638,7 +12638,16 @@ inline bool ThreadPool::enqueue(std::function fn) { if (jobs_.size() > idle_thread_count_ && threads_.size() + dynamic_threads_.size() < max_thread_count_) { cleanup_finished_threads(); - dynamic_threads_.emplace_back(std::thread([this]() { worker(true); })); +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + try { +#endif + dynamic_threads_.emplace_back(std::thread([this]() { worker(true); })); +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + } catch (const std::system_error &) { + // No thread budget left: keep the job queued for an existing worker + // instead of letting the exception escape the accept loop. + } +#endif } }