From c8e3bcf79b3931dad9ce16fecc714d39d2247f89 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 1 Jun 2022 13:46:33 +0200 Subject: MDEV-11026 Make InnoDB number of IO write/read threads dynamic Fix concurrency error - avoid accessing deleted memory, when io_slots is resized. the deleted memory in this case was vftable pointer in aiocb::m_internal_task The fix avoids calling dummy release function, via a flag in task_group. --- tpool/task_group.cc | 22 +++++++++++++++++++--- tpool/tpool.h | 4 +++- 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'tpool') diff --git a/tpool/task_group.cc b/tpool/task_group.cc index b52fe7c0f67..eb57a8bee37 100644 --- a/tpool/task_group.cc +++ b/tpool/task_group.cc @@ -25,11 +25,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ #endif namespace tpool { - task_group::task_group(unsigned int max_concurrency) : + + /** + Task_group constructor + + @param max_threads - maximum number of threads allowed to execute + tasks from the group at the same time. + + @param enable_task_release - if true (default), task::release() will be + called after task execution.'false' should only be used in rare cases + when accessing memory, pointed by task structures, would be unsafe after. + the callback. Also 'false' is only possible ,if task::release() is a trivial function + */ + task_group::task_group(unsigned int max_concurrency, + bool enable_task_release) + : m_queue(8), m_mtx(), m_tasks_running(), - m_max_concurrent_tasks(max_concurrency) + m_max_concurrent_tasks(max_concurrency), + m_enable_task_release(enable_task_release) {}; void task_group::set_max_tasks(unsigned int max_concurrency) @@ -53,7 +68,8 @@ namespace tpool if (t) { t->m_func(t->m_arg); - t->release(); + if (m_enable_task_release) + t->release(); } lk.lock(); diff --git a/tpool/tpool.h b/tpool/tpool.h index 5ce886d83b5..f0b2b9f6735 100644 --- a/tpool/tpool.h +++ b/tpool/tpool.h @@ -68,8 +68,10 @@ private: std::condition_variable m_cv; unsigned int m_tasks_running; unsigned int m_max_concurrent_tasks; + const bool m_enable_task_release; + public: - task_group(unsigned int max_concurrency= 100000); + task_group(unsigned int max_concurrency= 100000, bool m_enable_task_release= true); void set_max_tasks(unsigned int max_concurrent_tasks); void execute(task* t); void cancel_pending(task *t); -- cgit v1.2.1