Skip to content
Permalink
Browse files
MDEV-21551 Fix calculation of current concurrency level in
maybe_wake_or_create_thread()

A task that is executed,could be counted as waiting (after wait_begin()
before wait_end()) or as long-running (callback runs for a long time).

If task is both marked waiting and long running, then calculation of
current concurrency (# of executing tasks - # of long tasks - #of waiting tasks)
is wrong, as task is counted twice.

Thus current concurrency could go negative, but with unsigned arithmetic
it will become a huge number.

As a result, maybe_wake_or_create_thread() would neither wake or create
a thread, when it should. Which may result in a deadlock.
  • Loading branch information
vaintroub committed Jan 21, 2020
1 parent 92d6c13 commit c20bf8f
Showing 1 changed file with 2 additions and 0 deletions.
@@ -559,6 +559,7 @@ void thread_pool_generic::maintainence()
thread_data = thread_data->m_next)
{
if (thread_data->is_executing_task() &&
!thread_data->is_waiting() &&
(thread_data->is_long_task()
|| (m_timestamp - thread_data->m_task_start_time > LONG_TASK_DURATION)))
{
@@ -708,6 +709,7 @@ void thread_pool_generic::maybe_wake_or_create_thread()
{
if (m_task_queue.empty())
return;
DBUG_ASSERT(m_active_threads.size() >= m_long_tasks_count + m_waiting_task_count);
if (m_active_threads.size() - m_long_tasks_count - m_waiting_task_count > m_concurrency)
return;
if (!m_standby_threads.empty())

0 comments on commit c20bf8f

Please sign in to comment.