74 |
void *data; |
void *data; |
75 |
}; |
}; |
76 |
|
|
77 |
/* The lists. */ |
/* List of file descriptors. */ |
78 |
static struct fd_list_node *input_list = 0, *output_list = 0; |
static struct fd_list_node *input_list = 0, *output_list = 0; |
79 |
static pqueue *timer_q = 0; |
|
80 |
|
/* Timer queue (all fields automatically initialized to 0). */ |
81 |
|
static pqueue timer_q; |
82 |
|
|
83 |
static volatile unsigned int recvd_signals = 0; |
static volatile unsigned int recvd_signals = 0; |
84 |
|
|
104 |
static time_t time_quantize (unsigned long int seconds, |
static time_t time_quantize (unsigned long int seconds, |
105 |
unsigned long int shift); |
unsigned long int shift); |
106 |
static void proc_timer (struct timer_pq_node *timer); |
static void proc_timer (struct timer_pq_node *timer); |
107 |
static int timer_eq (void*,void*); |
static int timer_eq (void *, void *); |
108 |
static RETSIGTYPE dmx_sighandler (int sig); |
static RETSIGTYPE dmx_sighandler (int sig); |
109 |
static void dispatch_signals (); |
static void dispatch_signals (); |
110 |
|
|
293 |
called until 'seconds' seconds have happened. */ |
called until 'seconds' seconds have happened. */ |
294 |
timer_id |
timer_id |
295 |
dmx_add_periodic_alarm (unsigned long int seconds, long int shift, |
dmx_add_periodic_alarm (unsigned long int seconds, long int shift, |
296 |
void (*callback) (void *), void *data) |
void (*callback) (void *), void *data) |
297 |
{ |
{ |
298 |
return timer_pq_add(shift < 0 ? get_uptime() + seconds |
return timer_pq_add (shift < 0 ? get_uptime() + seconds |
299 |
: time_quantize(seconds, shift), |
: time_quantize(seconds, shift), |
300 |
seconds, shift, callback, data); |
seconds, shift, callback, data); |
301 |
} |
} |
302 |
|
|
303 |
/* Call 'callback' with 'data' as parameter in 'seconds' seconds from now. */ |
/* Call 'callback' with 'data' as parameter in 'seconds' seconds from now. */ |
304 |
timer_id |
timer_id |
305 |
dmx_add_timer (unsigned long int seconds, void (*callback) (void *), |
dmx_add_timer (unsigned long int seconds, void (*callback) (void *), |
306 |
void *data) |
void *data) |
307 |
{ |
{ |
308 |
return timer_pq_add(get_uptime() + seconds, 0, 0, callback, data); |
return timer_pq_add (get_uptime() + seconds, 0, 0, callback, data); |
309 |
} |
} |
310 |
|
|
311 |
/* Check if timer needs to be dispatched and do it. Use when you are |
/* Check if timer needs to be dispatched and do it. Use when you are |
314 |
dmx_dispatch_timer (timer_id id) |
dmx_dispatch_timer (timer_id id) |
315 |
{ |
{ |
316 |
struct timer_pq_node *node; |
struct timer_pq_node *node; |
317 |
struct timer_pq_node *node_aux = |
struct timer_pq_node tmp_node; |
318 |
(struct timer_pq_node*)malloc(sizeof(struct timer_pq_node)); |
|
319 |
node_aux->id=id; |
tmp_node.id = id; |
320 |
node=pq_get_func(node_aux,timer_q); |
node = pq_get_func (&tmp_node, &timer_q); |
321 |
free(node_aux); |
|
322 |
if(node && get_uptime() >= node->next_alarm) |
if (node && get_uptime() >= node->next_alarm) |
323 |
proc_timer(node); |
proc_timer (node); |
324 |
} |
} |
325 |
|
|
326 |
/* Call 'callback' when signal 'signum' arrives. This function must be used |
/* Call 'callback' when signal 'signum' arrives. This function must be used |
361 |
void * |
void * |
362 |
dmx_remove_timer (timer_id id) |
dmx_remove_timer (timer_id id) |
363 |
{ |
{ |
364 |
struct timer_pq_node *node= |
struct timer_pq_node tmp_node; |
365 |
(struct timer_pq_node*)malloc(sizeof(struct timer_pq_node)); |
struct timer_pq_node* node; |
366 |
void *ret; |
void *data = NULL; |
367 |
node->id=id; |
|
368 |
ret=pq_del_func(node,timer_q); |
tmp_node.id = id; |
369 |
free(node); |
node = (struct timer_pq_node *)pq_del_func (&tmp_node, &timer_q); |
370 |
return ret; |
if (node) { |
371 |
|
data = node->data; |
372 |
|
free (node); |
373 |
|
} |
374 |
|
|
375 |
|
return data; |
376 |
} |
} |
377 |
|
|
378 |
|
/* Compare function for timers. */ |
379 |
static int |
static int |
380 |
timer_eq (void *timer,void *timer2) |
timer_eq (void *timer, void *timer2) |
381 |
{ |
{ |
382 |
return timer && timer2 && ((struct timer_pq_node*)timer)->id |
return timer && timer2 && ((struct timer_pq_node *)timer)->id |
383 |
==((struct timer_pq_node*)timer2)->id; |
== ((struct timer_pq_node *)timer2)->id; |
384 |
} |
} |
385 |
|
|
386 |
/* Stop reporting signal 'signum'. Restores default action for the signal. */ |
/* Stop reporting signal 'signum'. Restores default action for the signal. */ |
479 |
*list = (void *)0; |
*list = (void *)0; |
480 |
} |
} |
481 |
|
|
482 |
/* Add a node to the timer list. */ |
/* Add a node to the timer queue. */ |
483 |
static timer_id |
static timer_id |
484 |
timer_pq_add(time_t next_alarm, unsigned long int time_incr, |
timer_pq_add (time_t next_alarm, unsigned long int time_incr, |
485 |
long int time_shift, void (*callback) (void *), |
long int time_shift, void (*callback) (void *), |
486 |
void *data) |
void *data) |
487 |
{ |
{ |
488 |
/* para el id de los timer */ |
static timer_id timer_id_cnt = 0; /* for timer identifiers */ |
|
static timer_id timer_id_cnt = 0; |
|
489 |
struct timer_pq_node *new_node; |
struct timer_pq_node *new_node; |
490 |
|
|
491 |
if(!timer_q){ |
if (timer_q.size == 0) { |
492 |
timer_q=(pqueue*)malloc(sizeof(pqueue)); |
/* not yet initialized */ |
493 |
if(!timer_q) |
if (pq_new (&timer_q, 127, timer_eq) < 0) |
|
return -1; |
|
|
timer_q->csize=0; |
|
|
if(pq_new(timer_q,100,timer_eq)<0) |
|
494 |
return -1; |
return -1; |
495 |
} |
} |
496 |
|
|
497 |
new_node = (struct timer_pq_node*)malloc(sizeof(struct timer_pq_node)); |
new_node = (struct timer_pq_node*)malloc (sizeof(struct timer_pq_node)); |
498 |
new_node->id = timer_id_cnt++; |
new_node->id = timer_id_cnt++; /* TODO may overflow! */ |
499 |
new_node->next_alarm = next_alarm; |
new_node->next_alarm = next_alarm; |
500 |
new_node->time_incr = time_incr; |
new_node->time_incr = time_incr; |
501 |
new_node->time_shift = time_shift; |
new_node->time_shift = time_shift; |
502 |
new_node->callback = callback; |
new_node->callback = callback; |
503 |
new_node->data = data; |
new_node->data = data; |
504 |
|
|
505 |
pq_add(next_alarm,new_node,timer_q); |
pq_add (next_alarm, new_node, &timer_q); |
506 |
|
|
507 |
return new_node->id; |
return new_node->id; |
508 |
} |
} |
509 |
|
|
510 |
/* Remove all nodes from the timer list. */ |
/* Remove all nodes from the timer queue. */ |
511 |
static void |
static void |
512 |
timer_pq_cleanup() |
timer_pq_cleanup () |
513 |
{ |
{ |
514 |
struct timer_pq_node *node; |
struct timer_pq_node *node = pq_del_min (&timer_q); |
515 |
for(;node;node=pq_del_min(timer_q)) |
|
516 |
free(node); |
for (node = pq_del_min (&timer_q); node; node = pq_del_min (&timer_q)) |
517 |
|
free (node); |
518 |
} |
} |
519 |
|
|
520 |
/* Find next timer. */ |
/* Find next timer. */ |
521 |
static struct timer_pq_node * |
static struct timer_pq_node * |
522 |
find_next_timer() |
find_next_timer () |
523 |
{ |
{ |
524 |
return (struct timer_pq_node*)pq_min(timer_q); |
return (struct timer_pq_node*)pq_min (&timer_q); |
525 |
} |
} |
526 |
|
|
527 |
/* Quantize time in 'seconds' and return the time of the next quantization. */ |
/* Quantize time in 'seconds' and return the time of the next quantization. */ |
549 |
time_t last_alarm, now; |
time_t last_alarm, now; |
550 |
void *data = timer->data; |
void *data = timer->data; |
551 |
void (*callback) (void *) = timer->callback; |
void (*callback) (void *) = timer->callback; |
552 |
|
struct timer_pq_node tmp_node; |
553 |
|
|
554 |
if (timer->time_incr) { |
if (timer->time_incr) { |
555 |
last_alarm = timer->next_alarm; |
last_alarm = timer->next_alarm; |
576 |
timer->next_alarm = now + timer->time_incr; |
timer->next_alarm = now + timer->time_incr; |
577 |
} |
} |
578 |
} |
} |
579 |
|
tmp_node.id = timer->id; |
580 |
|
pq_chpri (&tmp_node, timer->next_alarm, &timer_q); |
581 |
} |
} |
582 |
else { |
else { |
583 |
dmx_remove_timer (timer->id); |
dmx_remove_timer (timer->id); |