diff options
Diffstat (limited to 'tpool')
-rw-r--r-- | tpool/tpool_generic.cc | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/tpool/tpool_generic.cc b/tpool/tpool_generic.cc index fd97b446..a4d6c405 100644 --- a/tpool/tpool_generic.cc +++ b/tpool/tpool_generic.cc @@ -628,7 +628,7 @@ void thread_pool_generic::check_idle(std::chrono::system_clock::time_point now) } /* Switch timer off after 1 minute of idle time */ - if (now - idle_since > max_idle_time) + if (now - idle_since > max_idle_time && m_active_threads.empty()) { idle_since= invalid_timestamp; switch_timer(timer_state_t::OFF); @@ -722,13 +722,17 @@ static int throttling_interval_ms(size_t n_threads,size_t concurrency) /* Create a new worker.*/ bool thread_pool_generic::add_thread() { - if (m_thread_creation_pending.test_and_set()) - return false; - size_t n_threads = thread_count(); if (n_threads >= m_max_threads) return false; + + /* + Deadlock danger exists, so monitor pool health + with maintenance timer. + */ + switch_timer(timer_state_t::ON); + if (n_threads >= m_min_threads) { auto now = std::chrono::system_clock::now(); @@ -739,12 +743,18 @@ bool thread_pool_generic::add_thread() Throttle thread creation and wakeup deadlock detection timer, if is it off. */ - switch_timer(timer_state_t::ON); - return false; } } + /* Check and set "thread creation pending" flag before creating the thread. We + reset the flag in thread_pool_generic::worker_main in new thread created. The + flag must be reset back in case we fail to create the thread. If this flag is + not reset all future attempt to create thread for this pool would not work as + we would return from here. */ + if (m_thread_creation_pending.test_and_set()) + return false; + worker_data *thread_data = m_thread_data_cache.get(); m_active_threads.push_back(thread_data); try @@ -764,6 +774,7 @@ bool thread_pool_generic::add_thread() "current number of threads in pool %zu\n", e.what(), thread_count()); warning_written = true; } + m_thread_creation_pending.clear(); return false; } return true; @@ -801,6 +812,7 @@ thread_pool_generic::thread_pool_generic(int min_threads, int max_threads) : m_tasks_dequeued(), m_wakeups(), m_spurious_wakeups(), + m_timer_state(timer_state_t::ON), m_in_shutdown(), m_timestamp(), m_long_tasks_count(), @@ -813,6 +825,7 @@ thread_pool_generic::thread_pool_generic(int min_threads, int max_threads) : m_maintenance_timer(thread_pool_generic::maintenance_func, this, nullptr) { set_concurrency(); + // start the timer m_maintenance_timer.set_time(0, (int)m_timer_interval.count()); } |