Use several timers with setitimer()
Hello,
I would like to use several timers with setitimer, but I have a problem. setitimer() with ITIMER_REAL, send always SIGALRM. Example: Code:
#include <sys/time.h> Is there other way to use several timers?? Best reagards. |
You can only set one timer with ITIMER_REAL.
What you will need to do is create a linked list with your timer timeout info inside of it. Like this; struct timeout { struct timeout *next, *prev; int diff; // num of secs til next timeout void *(func)(); // callback func }; struct timeout *timerlist = NULL; void callback_timeout(int i) { // walk items on timerlist // first item is timer that this popped for // reset timer for next item in list // callback func for this timeout } int register_timeout(int when, void *(what)()) // when : in secs to timeout // what : callback func { struct timeout *pto = (struct timeout *) malloc(sizeof(struct timeout)); struct timeout *iter; pto->diff = when; pto->func = what; sigblock(SIGALRM); // don't bother me while i'm adding to the list if (NULL == timerlist) { pto->next = pto->prev = pto; timerlist = pto; itimer.it_value.tv_sec = pto->diff; itimer.it_value.tv_usec = 0; // set timer for first time setitimer(ITIMER_REAL, &itimer, 0); signal(SIGALRM, callback_timeout); sigunblock(SIGALRM); return 0; } iter = timerlist; do { if (pto->diff > iter->diff) { // bigger that current pto->diff = pto->diff - iter->diff; iter = iter->next; } else { // eq or less than // insert at front // decrement diff from every member in list pto->prev = iter->prev; pto->next = iter; iter = pto->prev->next = pto; if (iter == timerlist) timerlist = pto; iter->diff = iter->diff - pto->diff; // set timer for new time itimer.it_value.tv_sec = pto->diff; itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, 0); signal(SIGALRM, callback_timeout); sigunblock(SIGALRM); return 0; } } while (iter != timerlist); // at end of list pto->diff = pto->diff - timerlist->prev->diff; timerlist->prev->next = pto; pto->prev - timerlist->prev; pto->next = timerlist; // timer already running sigunblock(SIGALRM); return 0; } |
All times are GMT -5. The time now is 09:38 AM. |