]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] Scheduler: Fix race between switch_scheduler_add_task() and task_thread_loop...
authorAndrey Volk <andywolk@gmail.com>
Fri, 23 Oct 2020 17:48:53 +0000 (21:48 +0400)
committerAndrey Volk <andywolk@gmail.com>
Tue, 16 Mar 2021 22:01:01 +0000 (01:01 +0300)
src/include/switch_scheduler.h
src/switch_scheduler.c

index 14403917ca773d876d1bee4525e63398091f1442..1100fdb05286986a1e2ac99b99cb32afbce97837 100644 (file)
@@ -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
index c08d1071b4de90fe1ac1133be924484fe6c30bf2..9c0f29a35b8f06950f8142b695af3842235e0f06 100644 (file)
@@ -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)
+{
+       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)
+                                                                                                  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)