allen allen - 5 months ago 23
Linux Question

How to handle multiple timer signals

int main ()
{
int i=0;
timer_t t_id[100];
for(i=0; i<100; i++)
makeTimer(NULL, &t_id[i], i+1, 0);

/* Do busy work. */
while (1);
}





static int makeTimer( char *name, timer_t *timerID, int sec, int msec )
{
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;

/* Set up signal handler. */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timer_handler;
sigemptyset(&sa.sa_mask);

if (sigaction(sigNo, &sa, NULL) == -1)
{
printf("sigaction error\n");
return -1;
}

/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);

its.it_interval.tv_sec = sec;
its.it_interval.tv_nsec = msec * 1000000;
its.it_value.tv_sec = sec;

its.it_value.tv_nsec = msec * 1000000;
timer_settime(*timerID, 0, &its, NULL);

return 0;
}

static void timer_handler( int sig, siginfo_t *si, void *uc )
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;

/* how to know the timer_id with index? */
}


On this code, I made a number of timers which id is made from array structure.

If the time out event has occurred, then all the timer shares the one timer_handler. But how can I know which index's(t_id[index]) time out has occurred?

Is it possible? I mean I want to know which index's time out has occurred.

Answer

A simple example using structures:

struct timer_event_data
{
    timer_t id;
    size_t  index;  // Array index, not really needed IMO
    // Other possible data
};

#define NUMBER_TIMER_EVENTS 100

int main(void)
{
    struct timer_event_data timer_data[NUMBER_TIMER_EVENTS];

    for (size_t i = 0; i < NUMBER_TIMER_EVENTS; ++i)
    {
        // Initialize structure
        timer_data[i].index = i;

        // Start timer
        makeTimer(NULL, &timer_data[i], i + 1, 0);
    }

    // Main processing loop
    for (;;)
    {
        // ...
    }

    return 0;
}

void makeTimer(const char *name, struct timer_event_data *timer_data, unsigned sec, unsigned msec)
{
    ...
    te.sigev_value.sival_ptr = timer_data;
    timer_create(CLOCK_REALTIME, &te, &timer_data->id);
    ...
}

static void timer_handler( int sig, siginfo_t *si, void *uc ) 
{
    struct timer_event_data *timer_data = si->si_value.sival_ptr;
    // Use data in structure any way you want
}
Comments