FreeSWITCH API Documentation  1.7.0
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_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
 
switch_thread_ttask_thread_p = NULL
 

Typedef Documentation

Definition at line 47 of file switch_scheduler.c.

Function Documentation

static void switch_scheduler_execute ( switch_scheduler_task_container_t tp)
static

Definition at line 58 of file switch_scheduler.c.

References switch_scheduler_task_container::desc, 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_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().

59 {
60  switch_event_t *event;
61  //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));
62 
63  tp->func(&tp->task);
64 
65  if (tp->task.repeat) {
66  tp->task.runtime = switch_epoch_time_now(NULL) + tp->task.repeat;
67  }
68 
69  if (tp->task.runtime > tp->executed) {
70  tp->executed = 0;
72  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
76  switch_queue_push(globals.event_queue, event);
77  event = NULL;
78  }
79  } else {
80  tp->destroyed = 1;
81  }
82 }
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_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:903
#define SWITCH_INT64_T_FMT
#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:383
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1129
static struct @6 globals
switch_scheduler_task_t task
static void* SWITCH_THREAD_FUNC switch_scheduler_task_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 178 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().

179 {
180  void *pop;
181  globals.task_thread_running = 1;
182 
183  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Starting task thread\n");
184  while (globals.task_thread_running == 1) {
185  if (task_thread_loop(0)) {
186  break;
187  }
188  if (switch_queue_pop_timeout(globals.event_queue, &pop, 500000) == SWITCH_STATUS_SUCCESS) {
189  switch_event_t *event = (switch_event_t *) pop;
190  switch_event_fire(&event);
191  }
192  }
193 
194  task_thread_loop(1);
195 
196  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Task thread ending\n");
197 
198  while(switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
199  switch_event_t *event = (switch_event_t *) pop;
200  switch_event_destroy(&event);
201  }
202 
203  globals.task_thread_running = 0;
204 
205  return NULL;
206 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
#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:1124
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:1140
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)
static struct @6 globals
static void* SWITCH_THREAD_FUNC task_own_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 84 of file switch_scheduler.c.

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

Referenced by task_thread_loop().

85 {
88 
89  pool = tp->pool;
90  tp->pool = NULL;
91 
94  tp->in_thread = 0;
95 
96  return NULL;
97 }
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:640
switch_memory_pool_t * pool
struct apr_pool_t switch_memory_pool_t
switch_memory_pool_t * pool
static int task_thread_loop ( int  done)
static

Definition at line 99 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().

100 {
101  switch_scheduler_task_container_t *tofree, *tp, *last = NULL;
102 
103 
104  switch_mutex_lock(globals.task_mutex);
105 
106  for (tp = globals.task_list; tp; tp = tp->next) {
107  if (done) {
108  tp->destroyed = 1;
109  } else if (!tp->destroyed) {
110  int64_t now = switch_epoch_time_now(NULL);
111  if (now >= tp->task.runtime && !tp->in_thread) {
112  int32_t diff = (int32_t) (now - tp->task.runtime);
113  if (diff > 1) {
114  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n",
115  diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
116  }
117  tp->executed = now;
120  switch_threadattr_t *thd_attr;
122  switch_threadattr_create(&thd_attr, tp->pool);
123  switch_threadattr_detach_set(thd_attr, 1);
124  tp->in_thread = 1;
125  switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool);
126  } else {
127  tp->running = 1;
128  switch_mutex_unlock(globals.task_mutex);
130  switch_mutex_lock(globals.task_mutex);
131  tp->running = 0;
132  }
133  }
134  }
135  }
136  switch_mutex_unlock(globals.task_mutex);
137  switch_mutex_lock(globals.task_mutex);
138  for (tp = globals.task_list; tp;) {
139  if (tp->destroyed && !tp->in_thread) {
140  switch_event_t *event;
141 
142  tofree = tp;
143  tp = tp->next;
144  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n",
145  tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group));
146 
147 
149  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tofree->task.task_id);
150  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tofree->desc);
152  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tofree->task.runtime);
153  switch_queue_push(globals.event_queue, event);
154  event = NULL;
155  }
156 
157  if (last) {
158  last->next = tofree->next;
159  } else {
160  globals.task_list = tofree->next;
161  }
162  switch_safe_free(tofree->task.group);
163  if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) {
164  free(tofree->task.cmd_arg);
165  }
166  switch_safe_free(tofree->desc);
167  free(tofree);
168  } else {
169  last = tp;
170  tp = tp->next;
171  }
172  }
173  switch_mutex_unlock(globals.task_mutex);
174 
175  return done;
176 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#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:279
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
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:789
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
struct switch_scheduler_task_container * next
#define SWITCH_INT64_T_FMT
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#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:383
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1129
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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:642
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:675
switch_memory_pool_t * pool
static struct @6 globals
switch_scheduler_task_t task

Variable Documentation

switch_queue_t* event_queue

Definition at line 54 of file switch_scheduler.c.

struct { ... } globals
switch_memory_pool_t* memory_pool

Definition at line 55 of file switch_scheduler.c.

uint32_t task_id

Definition at line 52 of file switch_scheduler.c.

Definition at line 50 of file switch_scheduler.c.

switch_mutex_t* task_mutex

Definition at line 51 of file switch_scheduler.c.

switch_thread_t* task_thread_p = NULL
int task_thread_running

Definition at line 53 of file switch_scheduler.c.