libamxp  1.4.0
Patterns C Implementation
amxp_scheduler.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <amxc/amxc.h>
#include <amxp/amxp_scheduler.h>
#include <amxc/amxc_macros.h>

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static void amxp_schedule_item_delete (amxc_llist_it_t *it)
 
static int amxp_scheduler_compare_items (amxc_llist_it_t *it1, amxc_llist_it_t *it2)
 
static void amxp_scheduler_reset_timer (amxp_scheduler_t *scheduler)
 
static void amxp_scheduler_emit (amxp_scheduler_t *scheduler, amxp_scheduler_item_t *item, const char *signal, uint32_t duration, bool trigger)
 
static void amxp_scheduler_item_stop (UNUSED amxp_timer_t *timer, void *priv)
 
static void amxp_scheduler_check_item (amxp_scheduler_t *scheduler, amxp_scheduler_item_t *item)
 
static void amxp_scheduler_trigger (amxp_timer_t *timer, void *priv)
 
static void amxp_scheduler_add_signal (amxp_scheduler_t *scheduler, const char *signal, const char *id)
 
static void amxp_scheduler_remove_signal (amxp_scheduler_t *scheduler, const char *signal, const char *id)
 
static amxp_scheduler_item_tamxp_scheduler_create_or_fetch (amxp_scheduler_t *scheduler, const char *id, uint32_t duration)
 
static void amxp_scheduler_insert (amxp_scheduler_t *scheduler, const char *id, amxp_scheduler_item_t *item)
 
int amxp_scheduler_new (amxp_scheduler_t **scheduler)
 Allocates a amxp_scheduler_t structures and initializes to an empty scheduler. More...
 
void amxp_scheduler_delete (amxp_scheduler_t **scheduler)
 Frees the previously allocated amxp_scheduler_t structure. More...
 
int amxp_scheduler_init (amxp_scheduler_t *scheduler)
 Initializes a amxp_scheduler_t to an empty scheduler. More...
 
void amxp_scheduler_clean (amxp_scheduler_t *scheduler)
 Cleans the scheduler. More...
 
int amxp_scheduler_enable (amxp_scheduler_t *scheduler, bool enable)
 Enables or disable the scheduler. More...
 
int amxp_scheduler_use_local_time (amxp_scheduler_t *scheduler, bool use_local_time)
 Use local time or UTC time in calculation for next trigger times. More...
 
int amxp_scheduler_update (amxp_scheduler_t *scheduler)
 Forces recalculation of the schedule items' next occurrence time. More...
 
int amxp_scheduler_connect (amxp_scheduler_t *scheduler, const char *id, amxp_slot_fn_t fn, void *priv)
 Connects a callback function to the scheduler. More...
 
int amxp_scheduler_disconnect (amxp_scheduler_t *scheduler, const char *id, amxp_slot_fn_t fn)
 Disconnects a callback function from the scheduler. More...
 
int amxp_scheduler_set_cron_item (amxp_scheduler_t *scheduler, const char *id, const char *cron_expr, uint32_t duration)
 Adds a schedule item or updates a schedule item using a cron expression. More...
 
int amxp_scheduler_set_cron_begin_end_item (amxp_scheduler_t *scheduler, const char *id, const char *cron_begin, const char *cron_end)
 Adds a schedule item or updates a schedule item using a cron expressions. More...
 
int amxp_scheduler_set_weekly_item (amxp_scheduler_t *scheduler, const char *id, const char *time, const char *days_of_week, uint32_t duration)
 Adds a schedule item or updates a schedule item using a time and list of week days. More...
 
int amxp_scheduler_set_weekly_begin_end_item (amxp_scheduler_t *scheduler, const char *id, const char *start_time, const char *end_time, const char *days_of_week)
 Adds a schedule item or updates a schedule item using a start time, end time and list of week days. More...
 
int amxp_scheduler_remove_item (amxp_scheduler_t *scheduler, const char *id)
 Removes a schedule item from the scheduler. More...
 
int amxp_scheduler_enable_item (amxp_scheduler_t *scheduler, const char *id, bool enable)
 Enables or disable a schedule item. More...
 
amxp_signal_mngr_tamxp_scheduler_get_sigmngr (amxp_scheduler_t *scheduler)
 Gets the signal manager of a scheduler. More...
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxp_scheduler.c.

Function Documentation

◆ amxp_schedule_item_delete()

static void amxp_schedule_item_delete ( amxc_llist_it_t *  it)
static

Definition at line 66 of file amxp_scheduler.c.

66  {
67  amxp_scheduler_item_t* item = amxc_container_of(it, amxp_scheduler_item_t, lit);
68 
69  amxp_cron_clean(&item->cron);
70  amxp_timer_delete(&item->timer);
71  amxc_htable_it_clean(&item->hit, NULL);
72  free(item);
73 }
void amxp_cron_clean(amxp_cron_expr_t *cron_expr)
Resets the amxp_cron_expr_t structure to the initialized state.
Definition: amxp_cron.c:477
void amxp_timer_delete(amxp_timer_t **timer)
Deletes a timer.
Definition: amxp_timer.c:247
Structure containing a schedule item.
amxp_cron_expr_t cron
amxc_htable_it_t hit
amxp_timer_t * timer

◆ amxp_scheduler_add_signal()

static void amxp_scheduler_add_signal ( amxp_scheduler_t scheduler,
const char *  signal,
const char *  id 
)
static

Definition at line 242 of file amxp_scheduler.c.

242  {
243  amxc_string_t strsignal;
244  amxc_string_init(&strsignal, 0);
245 
246  amxc_string_setf(&strsignal, "%s:%s", signal, id);
247  amxp_sigmngr_add_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0));
248 
249  amxc_string_clean(&strsignal);
250 }
int amxp_sigmngr_add_signal(amxp_signal_mngr_t *const sig_mngr, const char *name)
Adds a signal to a signal manager.
Definition: amxp_signal.c:433
amxp_signal_mngr_t sigmngr

◆ amxp_scheduler_check_item()

static void amxp_scheduler_check_item ( amxp_scheduler_t scheduler,
amxp_scheduler_item_t item 
)
static

Definition at line 151 of file amxp_scheduler.c.

152  {
153  amxc_ts_t now;
154  amxc_ts_t prev = { 0, 0, 0};
155  uint32_t duration = 0;
156  amxc_ts_now(&now);
157 
158  when_false(scheduler->sigmngr.enabled, exit);
159  when_false(item->enabled, exit);
160  if((item->duration == 0) && !item->end_time_is_set) {
161  if((item->timer != NULL) && (item->timer->state == amxp_timer_running)) {
162  amxp_scheduler_emit(scheduler, item, "stop", 0, false);
163  amxp_timer_delete(&item->timer);
164  }
165  goto exit;
166  }
167 
168  if(scheduler->use_local_time) {
169  amxc_ts_to_local(&now);
170  }
171 
172  duration = item->duration;
173  amxp_cron_prev(&item->cron, &now, &prev);
174  if((duration == 0) && item->end_time_is_set) {
175  amxc_ts_t end = { 0, 0, 0};
176  amxp_cron_next(&item->end_cron, &prev, &end);
177  duration = end.sec - prev.sec;
178  }
179 
180  prev.sec += duration;
181  if(prev.sec > now.sec) {
182  if(item->timer == NULL) {
184  }
185  if(item->timer->state != amxp_timer_running) {
186  amxp_scheduler_emit(scheduler, item, "start", prev.sec - now.sec, false);
187  }
188  amxp_timer_start(item->timer, (prev.sec - now.sec) * 1000);
189  } else {
190  if((item->timer != NULL) && (item->timer->state == amxp_timer_running)) {
191  amxp_scheduler_emit(scheduler, item, "stop", 0, false);
192  amxp_timer_delete(&item->timer);
193  }
194  }
195 
196 exit:
197  return;
198 }
static void amxp_scheduler_item_stop(UNUSED amxp_timer_t *timer, void *priv)
static void amxp_scheduler_emit(amxp_scheduler_t *scheduler, amxp_scheduler_item_t *item, const char *signal, uint32_t duration, bool trigger)
int amxp_cron_prev(const amxp_cron_expr_t *expr, const amxc_ts_t *ref, amxc_ts_t *next)
Calculates the previous trigger time for a parsed cron expression.
Definition: amxp_cron.c:588
int amxp_cron_next(const amxp_cron_expr_t *expr, const amxc_ts_t *ref, amxc_ts_t *next)
Calculates the next trigger time for a parsed cron expression.
Definition: amxp_cron.c:631
int amxp_timer_start(amxp_timer_t *timer, unsigned int timeout_msec)
Starts or resets a timer.
Definition: amxp_timer.c:296
int amxp_timer_new(amxp_timer_t **timer, amxp_timer_cb_t cb, void *priv)
Allocate and initializes a new timer.
Definition: amxp_timer.c:229
@ amxp_timer_running
Definition: amxp_timer.h:151
amxp_timer_state_t state
Definition: amxp_timer.h:166
amxp_cron_expr_t end_cron
bool use_local_time

◆ amxp_scheduler_compare_items()

static int amxp_scheduler_compare_items ( amxc_llist_it_t *  it1,
amxc_llist_it_t *  it2 
)
static

Definition at line 75 of file amxp_scheduler.c.

75  {
76  amxp_scheduler_item_t* item1 = amxc_container_of(it1, amxp_scheduler_item_t, lit);
77  amxp_scheduler_item_t* item2 = amxc_container_of(it2, amxp_scheduler_item_t, lit);
78 
79  return item1->next.sec - item2->next.sec;
80 }

◆ amxp_scheduler_create_or_fetch()

static amxp_scheduler_item_t* amxp_scheduler_create_or_fetch ( amxp_scheduler_t scheduler,
const char *  id,
uint32_t  duration 
)
static

Definition at line 270 of file amxp_scheduler.c.

272  {
273  amxp_scheduler_item_t* item = NULL;
274  amxc_htable_it_t* hit = NULL;
275  bool enabled = true;
276 
277  when_null(scheduler, exit);
278  when_str_empty(id, exit);
279 
280  hit = amxc_htable_get(&scheduler->items, id);
281  if(hit != NULL) {
282  item = amxc_container_of(hit, amxp_scheduler_item_t, hit);
283  enabled = item != NULL? item->enabled:true;
284  } else {
285  item = (amxp_scheduler_item_t*) calloc(1, sizeof(amxp_scheduler_item_t));
286  }
287  when_null(item, exit);
288 
289  item->duration = duration;
290  item->enabled = enabled;
291 
292 exit:
293  return item;
294 }
amxc_htable_t items

◆ amxp_scheduler_emit()

static void amxp_scheduler_emit ( amxp_scheduler_t scheduler,
amxp_scheduler_item_t item,
const char *  signal,
uint32_t  duration,
bool  trigger 
)
static

Definition at line 105 of file amxp_scheduler.c.

109  {
110  amxc_var_t data;
111  amxc_string_t strsignal;
112  amxp_signal_t* s = NULL;
113  const char* id = amxc_htable_it_get_key(&item->hit);
114  amxc_var_init(&data);
115  amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
116  amxc_var_add_key(cstring_t, &data, "id", id);
117  amxc_string_init(&strsignal, 0);
118 
119  amxc_string_setf(&strsignal, "%s:%s", signal, id);
120 
121  if(duration != 0) {
122  amxc_var_add_key(uint32_t, &data, "duration", duration);
123  }
124 
125  amxc_var_add_key(cstring_t, &data, "reason", signal);
126 
127  s = amxp_sigmngr_find_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0));
128  when_null(s, exit);
129  if(trigger) {
130  if(!s->triggered) {
131  amxp_sigmngr_trigger_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0), &data);
132  }
133  } else {
134  amxp_sigmngr_emit_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0), &data);
135  }
136 
137 exit:
138  amxc_string_clean(&strsignal);
139  amxc_var_clean(&data);
140 }
void amxp_sigmngr_trigger_signal(amxp_signal_mngr_t *const sig_mngr, const char *name, const amxc_var_t *const data)
Triggers a signal.
Definition: amxp_signal.c:492
amxp_signal_t * amxp_sigmngr_find_signal(const amxp_signal_mngr_t *const sig_mngr, const char *name)
Get the pointer to the signal.
Definition: amxp_signal.c:475
int amxp_sigmngr_emit_signal(const amxp_signal_mngr_t *const sig_mngr, const char *name, const amxc_var_t *const data)
Emits a signal.
Definition: amxp_signal.c:514
Structure containing the signal information.
Definition: amxp_signal.h:119

◆ amxp_scheduler_insert()

static void amxp_scheduler_insert ( amxp_scheduler_t scheduler,
const char *  id,
amxp_scheduler_item_t item 
)
static

Definition at line 296 of file amxp_scheduler.c.

298  {
299 
300  amxc_ts_t now;
301 
302  amxc_ts_now(&now);
303  if(scheduler->use_local_time) {
304  amxc_ts_to_local(&now);
305  }
306 
307  amxp_cron_next(&item->cron, &now, &item->next);
308  amxc_llist_prepend(&scheduler->ordered_items, &item->lit);
309  amxc_htable_insert(&scheduler->items, id, &item->hit);
310 
311  amxp_scheduler_add_signal(scheduler, "trigger", id);
312  amxp_scheduler_add_signal(scheduler, "start", id);
313  amxp_scheduler_add_signal(scheduler, "stop", id);
314 
315  amxp_scheduler_check_item(scheduler, item);
316  amxp_scheduler_reset_timer(scheduler);
317 }
static void amxp_scheduler_reset_timer(amxp_scheduler_t *scheduler)
static void amxp_scheduler_add_signal(amxp_scheduler_t *scheduler, const char *signal, const char *id)
static void amxp_scheduler_check_item(amxp_scheduler_t *scheduler, amxp_scheduler_item_t *item)
amxc_llist_it_t lit
amxc_llist_t ordered_items

◆ amxp_scheduler_item_stop()

static void amxp_scheduler_item_stop ( UNUSED amxp_timer_t timer,
void *  priv 
)
static

Definition at line 143 of file amxp_scheduler.c.

143  {
145  amxp_scheduler_t* scheduler = amxc_container_of(item->lit.llist, amxp_scheduler_t, ordered_items);
146 
147  amxp_timer_delete(&item->timer);
148  amxp_scheduler_emit(scheduler, item, "stop", 0, false);
149 }
Structure containing a scheduler.

◆ amxp_scheduler_remove_signal()

static void amxp_scheduler_remove_signal ( amxp_scheduler_t scheduler,
const char *  signal,
const char *  id 
)
static

Definition at line 252 of file amxp_scheduler.c.

252  {
253  amxc_string_t strsignal;
254  amxp_signal_t* s = NULL;
255  amxc_string_init(&strsignal, 0);
256 
257  amxc_string_setf(&strsignal, "%s:%s", signal, id);
258  s = amxp_sigmngr_find_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0));
259  if(s != NULL) {
260  if(s->triggered) {
261  amxp_sigmngr_remove_signal(&scheduler->sigmngr, amxc_string_get(&strsignal, 0));
262  } else {
263  amxp_signal_delete(&s);
264  }
265  }
266 
267  amxc_string_clean(&strsignal);
268 }
int amxp_sigmngr_remove_signal(amxp_signal_mngr_t *const sig_mngr, const char *name)
Removes a signal from a signal manager.
Definition: amxp_signal.c:448
int amxp_signal_delete(amxp_signal_t **signal)
Destructor function, deletes a signal.
Definition: amxp_signal.c:669

◆ amxp_scheduler_reset_timer()

static void amxp_scheduler_reset_timer ( amxp_scheduler_t scheduler)
static

Definition at line 82 of file amxp_scheduler.c.

82  {
83  amxc_llist_it_t* it = NULL;
84  amxp_scheduler_item_t* item = NULL;
85  uint64_t next = 0;
86 
87  amxc_llist_sort(&scheduler->ordered_items, amxp_scheduler_compare_items);
88  it = amxc_llist_get_first(&scheduler->ordered_items);
89  if(it == NULL) {
90  amxp_timer_stop(scheduler->timer);
91  goto exit;
92  }
93 
94  item = amxc_container_of(it, amxp_scheduler_item_t, lit);
95  next = amxp_cron_time_until_next(&item->cron, scheduler->use_local_time);
96 
97  if(scheduler->sigmngr.enabled) {
98  amxp_timer_start(scheduler->timer, next * 1000);
99  }
100 
101 exit:
102  return;
103 }
static int amxp_scheduler_compare_items(amxc_llist_it_t *it1, amxc_llist_it_t *it2)
int64_t amxp_cron_time_until_next(const amxp_cron_expr_t *expr, bool local)
Calculates the time in seconds until next trigger of a parsed cron expression occurs.
Definition: amxp_cron.c:673
int amxp_timer_stop(amxp_timer_t *timer)
Stops the timer.
Definition: amxp_timer.c:319
amxp_timer_t * timer

◆ amxp_scheduler_trigger()

static void amxp_scheduler_trigger ( amxp_timer_t timer,
void *  priv 
)
static

Definition at line 200 of file amxp_scheduler.c.

200  {
201  amxp_scheduler_t* scheduler = (amxp_scheduler_t*) priv;
202  amxc_llist_it_t* it = amxc_llist_get_first(&scheduler->ordered_items);
203  amxp_scheduler_item_t* item = amxc_container_of(it, amxp_scheduler_item_t, lit);
204  amxc_ts_t now;
205  uint32_t duration = 0;
206 
207  when_false(timer == scheduler->timer, exit);
208  amxc_ts_now(&now);
209 
210  if(scheduler->use_local_time) {
211  amxc_ts_to_local(&now);
212  }
213 
214  while(it != NULL && item->next.sec <= now.sec) {
215  if(item->enabled) {
216  duration = item->duration;
217  if((duration == 0) && item->end_time_is_set) {
218  amxc_ts_t end = { 0, 0, 0};
219  amxp_cron_next(&item->end_cron, &now, &end);
220  duration = end.sec - now.sec;
221  }
222  if(duration == 0) {
223  amxp_scheduler_emit(scheduler, item, "trigger", 0, false);
224  } else {
225  amxp_scheduler_emit(scheduler, item, "start", duration, false);
227  amxp_timer_start(item->timer, duration * 1000);
228  }
229  }
230  amxp_cron_next(&item->cron, &now, &item->next);
231  it = amxc_llist_it_get_next(it);
232  if(it != NULL) {
233  item = amxc_container_of(it, amxp_scheduler_item_t, lit);
234  }
235  }
236 
237  amxp_scheduler_reset_timer(scheduler);
238 exit:
239  return;
240 }