RTS API Documentation  1.10.11
Data Structures | Typedefs | Functions | Variables
switch_scheduler.c File Reference
#include <switch.h>
+ Include dependency graph for switch_scheduler.c:

Go to the source code of this file.

Data Structures

struct  switch_scheduler_task_container
 

Typedefs

typedef struct switch_scheduler_task_container switch_scheduler_task_container_t
 

Functions

static void switch_scheduler_execute (switch_scheduler_task_container_t *tp)
 
static void *SWITCH_THREAD_FUNC task_own_thread (switch_thread_t *thread, void *obj)
 
static int task_thread_loop (int done)
 
static void *SWITCH_THREAD_FUNC switch_scheduler_task_thread (switch_thread_t *thread, void *obj)
 
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)
 Schedule a task in the future. More...
 
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)
 Schedule a task in the future. More...
 
uint32_t switch_scheduler_del_task_id (uint32_t task_id)
 Delete a scheduled task. More...
 
uint32_t switch_scheduler_del_task_group (const char *group)
 Delete a scheduled task based on the group name. More...
 
void switch_scheduler_task_thread_start (void)
 Start the scheduler system. More...
 
void switch_scheduler_task_thread_stop (void)
 Stop the scheduler system. More...
 

Variables

struct {
   switch_scheduler_task_container_t *   task_list
 
   switch_mutex_t *   task_mutex
 
   uint32_t   task_id
 
   int   task_thread_running
 
   switch_queue_t *   event_queue
 
   switch_memory_pool_t *   memory_pool
 
globals = { 0 }
 
switch_thread_ttask_thread_p = NULL
 

Typedef Documentation

◆ switch_scheduler_task_container_t

Definition at line 48 of file switch_scheduler.c.

Function Documentation

◆ switch_scheduler_execute()

static void switch_scheduler_execute ( switch_scheduler_task_container_t tp)
static

Definition at line 59 of file switch_scheduler.c.

References switch_scheduler_task_container::desc, switch_scheduler_task_container::destroy_requested, switch_scheduler_task_container::destroyed, switch_scheduler_task_container::executed, switch_scheduler_task_container::func, globals, switch_scheduler_task::group, switch_scheduler_task::repeat, switch_scheduler_task::runtime, switch_epoch_time_now(), switch_event_add_header(), switch_event_add_header_string(), switch_event_create, SWITCH_EVENT_RE_SCHEDULE, SWITCH_INT64_T_FMT, switch_mutex_lock(), switch_mutex_unlock(), switch_queue_push(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_scheduler_task_container::task, and switch_scheduler_task::task_id.

Referenced by task_own_thread(), and task_thread_loop().

60 {
61  switch_event_t *event;
62  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing task %u %s (%s)\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
63 
64  tp->func(&tp->task);
65 
66  switch_mutex_lock(globals.task_mutex);
67  if (tp->task.repeat) {
68  tp->task.runtime = switch_epoch_time_now(NULL) + tp->task.repeat;
69  }
70 
71  if (!tp->destroy_requested && tp->task.runtime > tp->executed) {
72  tp->executed = 0;
74  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
78  switch_queue_push(globals.event_queue, event);
79  event = NULL;
80  }
81  } else {
82  tp->destroyed = 1;
83  }
84  switch_mutex_unlock(globals.task_mutex);
85 }
switch_scheduler_func_t func
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
#define SWITCH_INT64_T_FMT
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
static struct @8 globals
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
switch_scheduler_task_t task

◆ switch_scheduler_task_thread()

static void* SWITCH_THREAD_FUNC switch_scheduler_task_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 181 of file switch_scheduler.c.

References globals, SWITCH_CHANNEL_LOG, switch_event_destroy(), switch_event_fire, SWITCH_LOG_NOTICE, switch_log_printf(), switch_queue_pop_timeout(), switch_queue_trypop(), SWITCH_STATUS_SUCCESS, and task_thread_loop().

Referenced by switch_scheduler_task_thread_start().

182 {
183  void *pop;
184  globals.task_thread_running = 1;
185 
186  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Starting task thread\n");
187  while (globals.task_thread_running == 1) {
188  if (task_thread_loop(0)) {
189  break;
190  }
191  if (switch_queue_pop_timeout(globals.event_queue, &pop, 500000) == SWITCH_STATUS_SUCCESS) {
192  switch_event_t *event = (switch_event_t *) pop;
193  switch_event_fire(&event);
194  }
195  }
196 
197  task_thread_loop(1);
198 
199  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Task thread ending\n");
200 
201  while(switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
202  switch_event_t *event = (switch_event_t *) pop;
203  switch_event_destroy(&event);
204  }
205 
206  globals.task_thread_running = 0;
207 
208  return NULL;
209 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
#define SWITCH_CHANNEL_LOG
switch_status_t switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout)
Definition: switch_apr.c:1248
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264
static struct @8 globals
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
static int task_thread_loop(int done)

◆ task_own_thread()

static void* SWITCH_THREAD_FUNC task_own_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 87 of file switch_scheduler.c.

References switch_scheduler_task_container::in_thread, switch_scheduler_task_container::pool, switch_core_destroy_memory_pool, and switch_scheduler_execute().

Referenced by task_thread_loop().

88 {
91 
92  pool = tp->pool;
93  tp->pool = NULL;
94 
97  tp->in_thread = 0;
98 
99  return NULL;
100 }
static void switch_scheduler_execute(switch_scheduler_task_container_t *tp)
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
struct fspr_pool_t switch_memory_pool_t
switch_memory_pool_t * pool

◆ task_thread_loop()

static int task_thread_loop ( int  done)
static

Definition at line 102 of file switch_scheduler.c.

References switch_scheduler_task::cmd_arg, switch_scheduler_task_container::desc, switch_scheduler_task_container::destroyed, switch_scheduler_task_container::executed, globals, switch_scheduler_task::group, switch_scheduler_task_container::in_thread, switch_scheduler_task_container::next, switch_scheduler_task_container::pool, switch_scheduler_task_container::running, switch_scheduler_task::runtime, SSHF_FREE_ARG, SSHF_OWN_THREAD, SWITCH_CHANNEL_LOG, switch_core_new_memory_pool, switch_epoch_time_now(), switch_event_add_header(), switch_event_add_header_string(), switch_event_create, SWITCH_EVENT_DEL_SCHEDULE, SWITCH_INT64_T_FMT, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_lock(), switch_mutex_unlock(), switch_queue_push(), switch_safe_free, switch_scheduler_execute(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_test_flag, switch_thread_create(), switch_threadattr_create(), switch_threadattr_detach_set(), switch_scheduler_task_container::task, switch_scheduler_task::task_id, task_own_thread(), and thread.

Referenced by switch_scheduler_task_thread().

103 {
104  switch_scheduler_task_container_t *tofree, *tp, *last = NULL;
105 
106 
107  switch_mutex_lock(globals.task_mutex);
108 
109  for (tp = globals.task_list; tp; tp = tp->next) {
110  if (done) {
111  tp->destroyed = 1;
112  } else if (!tp->destroyed) {
113  int64_t now = switch_epoch_time_now(NULL);
114  if (now >= tp->task.runtime && !tp->in_thread) {
115  int32_t diff = (int32_t) (now - tp->task.runtime);
116  if (diff > 1) {
117  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n",
118  diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
119  }
120  tp->executed = now;
123  switch_threadattr_t *thd_attr;
125  switch_threadattr_create(&thd_attr, tp->pool);
126  switch_threadattr_detach_set(thd_attr, 1);
127  tp->in_thread = 1;
128  switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool);
129  } else {
130  tp->running = 1;
131  switch_mutex_unlock(globals.task_mutex);
133  switch_mutex_lock(globals.task_mutex);
134  tp->running = 0;
135  }
136  }
137  }
138  }
139  switch_mutex_unlock(globals.task_mutex);
140  switch_mutex_lock(globals.task_mutex);
141  for (tp = globals.task_list; tp;) {
142  if (tp->destroyed && !tp->in_thread) {
143  switch_event_t *event;
144 
145  tofree = tp;
146  tp = tp->next;
147  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n",
148  tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group));
149 
150 
152  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tofree->task.task_id);
153  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tofree->desc);
155  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tofree->task.runtime);
156  switch_queue_push(globals.event_queue, event);
157  event = NULL;
158  }
159 
160  if (last) {
161  last->next = tofree->next;
162  } else {
163  globals.task_list = tofree->next;
164  }
165  switch_safe_free(tofree->task.group);
166  if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) {
167  free(tofree->task.cmd_arg);
168  }
169  switch_safe_free(tofree->desc);
170  free(tofree);
171  } else {
172  last = tp;
173  tp = tp->next;
174  }
175  }
176  switch_mutex_unlock(globals.task_mutex);
177 
178  return done;
179 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
#define SWITCH_CHANNEL_LOG
static void *SWITCH_THREAD_FUNC task_own_thread(switch_thread_t *thread, void *obj)
static void switch_scheduler_execute(switch_scheduler_task_container_t *tp)
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
static switch_thread_t * thread
Definition: switch_log.c:486
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:678
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
struct switch_scheduler_task_container * next
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
#define SWITCH_INT64_T_FMT
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
static struct @8 globals
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
switch_memory_pool_t * pool
struct fspr_thread_t switch_thread_t
Definition: switch_apr.h:941
switch_scheduler_task_t task

Variable Documentation

◆ event_queue

switch_queue_t* event_queue

Definition at line 55 of file switch_scheduler.c.

◆ globals

struct { ... } globals

◆ memory_pool

switch_memory_pool_t* memory_pool

Definition at line 56 of file switch_scheduler.c.

◆ task_id

uint32_t task_id

Definition at line 53 of file switch_scheduler.c.

Referenced by switch_scheduler_add_task().

◆ task_list

Definition at line 51 of file switch_scheduler.c.

◆ task_mutex

switch_mutex_t* task_mutex

Definition at line 52 of file switch_scheduler.c.

◆ task_thread_p

switch_thread_t* task_thread_p = NULL

◆ task_thread_running

int task_thread_running

Definition at line 54 of file switch_scheduler.c.