103 |
static time_t time_quantize (unsigned long int seconds, |
static time_t time_quantize (unsigned long int seconds, |
104 |
unsigned long int shift); |
unsigned long int shift); |
105 |
static void proc_timer (struct timer_pq_node *timer); |
static void proc_timer (struct timer_pq_node *timer); |
|
static int timer_eq (void *, void *); |
|
106 |
static RETSIGTYPE dmx_sighandler (int sig); |
static RETSIGTYPE dmx_sighandler (int sig); |
107 |
static void dispatch_signals (); |
static void dispatch_signals (); |
108 |
|
|
311 |
void |
void |
312 |
dmx_dispatch_timer (timer_id id) |
dmx_dispatch_timer (timer_id id) |
313 |
{ |
{ |
314 |
struct timer_pq_node *node; |
if (get_uptime() >= id->next_alarm) |
315 |
|
proc_timer (id); |
|
node = pq_get_func (id, &timer_q); |
|
|
|
|
|
if (node && get_uptime() >= node->next_alarm) |
|
|
proc_timer (node); |
|
316 |
} |
} |
317 |
|
|
318 |
/* Call 'callback' when signal 'signum' arrives. This function must be used |
/* Call 'callback' when signal 'signum' arrives. This function must be used |
356 |
struct timer_pq_node* node; |
struct timer_pq_node* node; |
357 |
void *data = NULL; |
void *data = NULL; |
358 |
|
|
359 |
node = (struct timer_pq_node *)pq_del_func (id, &timer_q); |
node = (struct timer_pq_node *)pq_del_ptr (id, &timer_q); |
360 |
if (node) { |
if (node) { |
361 |
data = node->data; |
data = node->data; |
362 |
free (node); |
free (node); |
365 |
return data; |
return data; |
366 |
} |
} |
367 |
|
|
|
/* Compare function for timers. */ |
|
|
static int |
|
|
timer_eq (void *timer, void *timer2) |
|
|
{ |
|
|
/* check if it's the same timer, copies not supported */ |
|
|
return timer == timer2; |
|
|
} |
|
|
|
|
368 |
/* Stop reporting signal 'signum'. Restores default action for the signal. */ |
/* Stop reporting signal 'signum'. Restores default action for the signal. */ |
369 |
void |
void |
370 |
dmx_remove_signal (int signum) |
dmx_remove_signal (int signum) |
471 |
|
|
472 |
if (timer_q.size == 0) { |
if (timer_q.size == 0) { |
473 |
/* not yet initialized */ |
/* not yet initialized */ |
474 |
if (pq_new (&timer_q, 127, timer_eq) < 0) |
if (pq_new (&timer_q, 127, NULL) < 0) |
475 |
return NULL; |
return NULL; |
476 |
} |
} |
477 |
|
|
528 |
static void |
static void |
529 |
proc_timer (struct timer_pq_node *timer) |
proc_timer (struct timer_pq_node *timer) |
530 |
{ |
{ |
531 |
time_t last_alarm, now; |
time_t last_alarm, next_alarm, now; |
532 |
void *data = timer->data; |
void *data = timer->data; |
533 |
void (*callback) (void *) = timer->callback; |
void (*callback) (void *) = timer->callback; |
534 |
struct timer_pq_node tmp_node; |
struct timer_pq_node tmp_node; |
535 |
|
|
536 |
if (timer->time_incr) { |
if (timer->time_incr) { |
537 |
last_alarm = timer->next_alarm; |
last_alarm = next_alarm = timer->next_alarm; |
538 |
if (timer->time_shift >= 0) { |
if (timer->time_shift >= 0) { |
539 |
timer->next_alarm = |
next_alarm = time_quantize (timer->time_incr, |
540 |
time_quantize (timer->time_incr, |
timer->time_shift); |
|
timer->time_shift); |
|
541 |
} |
} |
542 |
/* TODO: We've got a problem here. Sometimes a periodic |
/* TODO: We've got a problem here. Sometimes a periodic |
543 |
alarm raises twice (eg. at 10:59:59 and 11:00:00). |
alarm raises twice (eg. at 10:59:59 and 11:00:00). |
544 |
By now I fix it avoiding an alarm raising twice in less |
By now I fix it avoiding an alarm raising twice in less |
545 |
than two seconds (Max). */ |
than two seconds (Max). */ |
546 |
#ifdef DMX_HI_RESOLUTION |
#ifdef DMX_HI_RESOLUTION |
547 |
if (timer->next_alarm == last_alarm) { |
if (next_alarm == last_alarm) { |
548 |
#else |
#else |
549 |
if (timer->next_alarm <= (last_alarm + 2)) { |
if (next_alarm <= (last_alarm + 2)) { |
550 |
#endif |
#endif |
551 |
/* quantize gave the same time, or shift was |
/* quantize gave the same time, or shift was |
552 |
-1, meaning quantization is not to be used */ |
-1, meaning quantization is not to be used */ |
553 |
timer->next_alarm += timer->time_incr; |
next_alarm += timer->time_incr; |
554 |
now = get_uptime (); |
now = get_uptime (); |
555 |
if (now > timer->next_alarm) { |
if (now > next_alarm) { |
556 |
/* maybe system time changed forward */ |
/* maybe system time changed forward */ |
557 |
timer->next_alarm = now + timer->time_incr; |
next_alarm = now + timer->time_incr; |
558 |
} |
} |
559 |
} |
} |
560 |
pq_chpri (timer, timer->next_alarm, &timer_q); |
/* this updates timer->next_alarm */ |
561 |
|
pq_chpri_ptr (timer, (prio_t)next_alarm, &timer_q); |
562 |
} |
} |
563 |
else { |
else { |
564 |
dmx_remove_timer (timer); |
dmx_remove_timer (timer); |