From 5ed17dd19cdda148c6d9f48b0dcc7ea9afb653cf Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 23 Oct 2020 21:48:53 +0400 Subject: [PATCH] [Core] Scheduler: Fix race between switch_scheduler_add_task() and task_thread_loop(). Add new switch_scheduler_add_task_ex() method. --- src/include/switch_scheduler.h | 17 +++++++++++++++++ src/switch_scheduler.c | 26 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/include/switch_scheduler.h b/src/include/switch_scheduler.h index 14403917ca..1100fdb052 100644 --- a/src/include/switch_scheduler.h +++ b/src/include/switch_scheduler.h @@ -66,6 +66,23 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_scheduler_func_t func, const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags); +/*! + \brief Schedule a task in the future + \param task_runtime the time in epoch seconds to execute the task. + \param func the callback function to execute when the task is executed. + \param desc an arbitrary description of the task. + \param group a group id tag to link multiple tasks to a single entity. + \param cmd_id an arbitrary index number be used in the callback. + \param cmd_arg user data to be passed to the callback. + \param flags flags to alter behaviour + \param task_id pointer to put the id of the task to + \return the id of the task +*/ + +SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(time_t task_runtime, + switch_scheduler_func_t func, + const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags, uint32_t *task_id); + /*! \brief Delete a scheduled task \param task_id the id of the task diff --git a/src/switch_scheduler.c b/src/switch_scheduler.c index c08d1071b4..9c0f29a35b 100644 --- a/src/switch_scheduler.c +++ b/src/switch_scheduler.c @@ -209,9 +209,21 @@ static void *SWITCH_THREAD_FUNC switch_scheduler_task_thread(switch_thread_t *th } SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, - switch_scheduler_func_t func, - const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags) + switch_scheduler_func_t func, + const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags) { + uint32_t task_id; + + switch_scheduler_add_task_ex(task_runtime, func, desc, group, cmd_id, cmd_arg, flags, &task_id); + + return task_id; +} + +SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(time_t task_runtime, + switch_scheduler_func_t func, + const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags, uint32_t *task_id) +{ + uint32_t result; switch_scheduler_task_container_t *container, *tp; switch_event_t *event; switch_time_t now = switch_epoch_time_now(NULL); @@ -220,6 +232,7 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_mutex_lock(globals.task_mutex); switch_zmalloc(container, sizeof(*container)); switch_assert(func); + switch_assert(task_id); if (task_runtime < now) { container->task.repeat = (uint32_t)task_runtime; @@ -246,8 +259,6 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, for (container->task.task_id = 0; !container->task.task_id; container->task.task_id = ++globals.task_id); - switch_mutex_unlock(globals.task_mutex); - tp = container; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %" SWITCH_INT64_T_FMT "\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), tp->task.runtime); @@ -260,7 +271,12 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_queue_push(globals.event_queue, event); event = NULL; } - return container->task.task_id; + + result = *task_id = container->task.task_id; + + switch_mutex_unlock(globals.task_mutex); + + return result; } SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_id(uint32_t task_id)