diff --git a/src/runtime/object.cpp b/src/runtime/object.cpp index 80c9735268..a3be15ffe9 100644 --- a/src/runtime/object.cpp +++ b/src/runtime/object.cpp @@ -754,14 +754,25 @@ class task_manager { unique_lock lock(m_mutex); m_idle_std_workers++; while (true) { - if (m_queues_size == 0 && m_shutting_down) { - break; + if (m_queues_size == 0) { + if (m_shutting_down) { + // We're done + break; + } + // Wait for new tasks + m_queue_cv.wait(lock); + continue; } - if (m_queues_size == 0 || - // If we have reached the maximum number of standard workers (because the - // maximum was decreased by `task_get`), wait for someone else to become - // idle before picking up new work. - m_std_workers.size() - m_idle_std_workers >= m_max_std_workers) { + + // There's work to be done. + // If we have reached the maximum number of standard workers (because the + // maximum was decreased by `task_get`), wait for someone else to become + // idle before picking up new work. + // But during shutdown, we skip this throttling: + // because the finalizer might have called m_queue_cv.notify_all() for the last + // time, we don't want to get stuck behind the wait(). + if (!m_shutting_down && + m_std_workers.size() - m_idle_std_workers >= m_max_std_workers) { m_queue_cv.wait(lock); continue; }