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.
This commit is contained in:
Vladislav Vaintroub 2022-06-01 13:46:33 +02:00
parent 49e660bb12
commit c8e3bcf79b
3 changed files with 23 additions and 6 deletions

View file

@ -84,8 +84,7 @@ private:
int m_max_aio;
public:
io_slots(int max_submitted_io, int max_callback_concurrency) :
m_cache(max_submitted_io),
m_group(max_callback_concurrency),
m_cache(max_submitted_io), m_group(max_callback_concurrency, false),
m_max_aio(max_submitted_io)
{
}

View file

@ -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();

View file

@ -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);