summaryrefslogtreecommitdiffstats
path: root/tpool/tpool_generic.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
commit347c164c35eddab388009470e6848cb361ac93f8 (patch)
tree2c0c44eac690f510bb0a35b2a13b36d606b77b6b /tpool/tpool_generic.cc
parentReleasing progress-linux version 1:10.11.7-4~progress7.99u1. (diff)
downloadmariadb-347c164c35eddab388009470e6848cb361ac93f8.tar.xz
mariadb-347c164c35eddab388009470e6848cb361ac93f8.zip
Merging upstream version 1:10.11.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tpool/tpool_generic.cc')
-rw-r--r--tpool/tpool_generic.cc25
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());
}