40 #include <ldns/ldns.h> 49 static const char* schedule_str =
"scheduler";
52 static pthread_cond_t *schedule_cond;
64 alarm_handler(sig_atomic_t sig)
73 pthread_cond_signal(schedule_cond);
77 schedule_str, (
int)sig);
90 time_t now = time_now();
91 task_type *task = get_first_task(schedule);
92 if (!task || task->
when == -1) {
94 }
else if (task->
when == 0 || task->
when <= now) {
99 alarm(task->
when - now);
107 static ldns_rbnode_t*
110 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(
sizeof(ldns_rbnode_t));
128 ldns_rbnode_t* first_node;
130 if (!schedule || !schedule->
tasks)
return NULL;
131 first_node = ldns_rbtree_first(schedule->
tasks);
132 if (!first_node)
return NULL;
146 ldns_rbnode_t *node, *delnode;
149 if (!schedule || !schedule->
tasks)
return NULL;
150 node = ldns_rbtree_first(schedule->
tasks);
151 if (!node)
return NULL;
152 delnode = ldns_rbtree_delete(schedule->
tasks, node->data);
155 if (!delnode)
return NULL;
156 delnode = ldns_rbtree_delete(schedule->
tasks_by_name, node->data);
158 if (!delnode)
return NULL;
170 task_delfunc(ldns_rbnode_t* elem,
int del_payload)
174 if (elem && elem != LDNS_RBTREE_NULL) {
176 task_delfunc(elem->left, del_payload);
177 task_delfunc(elem->right, del_payload);
192 struct sigaction action;
196 ods_log_error(
"[%s] unable to create: malloc failed", schedule_str);
202 pthread_mutex_init(&schedule->schedule_lock, NULL);
203 pthread_cond_init(&schedule->schedule_cond, NULL);
205 schedule_cond = &schedule->schedule_cond;
207 action.sa_handler = (void (*)(int))&alarm_handler;
208 sigfillset(&action.sa_mask);
210 sigaction(SIGALRM, &action, NULL);
222 if (!schedule)
return;
229 if (schedule->
tasks) {
230 task_delfunc(schedule->
tasks->root, 1);
232 ldns_rbtree_free(schedule->
tasks);
234 schedule->
tasks = NULL;
251 if (!schedule || !schedule->
tasks)
return -1;
254 task = get_first_task(schedule);
257 else if (task->
flush)
268 if (!schedule || !schedule->
tasks)
return 0;
269 return schedule->
tasks->count;
279 if (!schedule || !schedule->
tasks)
return;
282 node = ldns_rbtree_first(schedule->
tasks);
283 while (node && node != LDNS_RBTREE_NULL) {
290 node = ldns_rbtree_next(node);
300 ldns_rbnode_t *node, *nextnode;
304 if (!schedule || !schedule->
tasks)
return 0;
307 node = ldns_rbtree_first(schedule->
tasks);
308 while (node && node != LDNS_RBTREE_NULL) {
309 nextnode = ldns_rbtree_next(node);
310 if (node->data && ((
task_type*)node->data)->what ==
id) {
313 node = ldns_rbtree_delete(schedule->
tasks, node->data);
320 ((
task_type*)node->data)->when = time_now();
321 if (!ldns_rbtree_insert(schedule->
tasks, node)) {
323 "after flush. A task has been lost!",
346 if (!schedule || !schedule->
tasks)
return;
350 while ((node = ldns_rbtree_first(schedule->
tasks)) !=
353 node = ldns_rbtree_delete(schedule->
tasks, node->data);
354 if (node == 0)
break;
358 while ((node = ldns_rbtree_first(schedule->
tasks_by_name)) !=
361 node = ldns_rbtree_delete(schedule->
tasks_by_name, node->data);
362 if (node == 0)
break;
372 time_t now = time_now();
376 task = get_first_task(schedule);
377 if (!task || (!task->
flush && (task->
when == -1 || task->
when > now))) {
383 task = pop_first_task(schedule);
395 task = pop_first_task(schedule);
403 ldns_rbnode_t *node1, *node2;
408 ods_log_error(
"[%s] unable to schedule task: no task", schedule_str);
409 return ODS_STATUS_ERR;
412 if (!schedule || !schedule->
tasks) {
415 return ODS_STATUS_ERR;
418 ods_log_debug(
"[%s] schedule task [%s] for %s", schedule_str,
422 status = ODS_STATUS_ERR;
423 if ((node1 = task2node(task))) {
425 if ((node2 = task2node(task))) {
426 if(ldns_rbtree_insert(schedule->
tasks, node2)) {
429 status = ODS_STATUS_OK;
453 node1 = ldns_rbtree_delete(schedule->
tasks, task2);
463 (void) ldns_rbtree_insert(schedule->
tasks, node1);
467 status = ODS_STATUS_OK;
schedule_type * schedule_create()
void ods_log_debug(const char *format,...)
pthread_mutex_t schedule_lock
task_type * schedule_pop_first_task(schedule_type *schedule)
void schedule_purge(schedule_type *schedule)
pthread_cond_t schedule_cond
ods_status schedule_task(schedule_type *schedule, task_type *task)
void ods_log_error(const char *format,...)
enum task_id_enum task_id
void ods_log_crit(const char *format,...)
void schedule_release_all(schedule_type *schedule)
time_t schedule_time_first(schedule_type *schedule)
task_type * schedule_pop_task(schedule_type *schedule)
void task_cleanup(task_type *task)
const char * task_what2str(int what)
task_type *(* clean_context)(task_type *task)
ldns_rbtree_t * tasks_by_name
int schedule_flush_type(schedule_type *schedule, task_id id)
const char * task_who2str(const char *who)
void schedule_cleanup(schedule_type *schedule)
int task_compare(const void *a, const void *b)
int task_compare_name(const void *a, const void *b)
void schedule_flush(schedule_type *schedule)
size_t schedule_taskcount(schedule_type *schedule)