user3354789
user3354789

Reputation: 11

how to solve the linux timer signal handler

why is not possible to have a multiple timer with single handler. I used the program from the below link and it is not working. He has explained the reason about the problem but it is not very clear. Is someone help me why is it not working ?? http://www.graphics-muse.org/wp/?p=868

Upvotes: 0

Views: 2703

Answers (2)

Duck
Duck

Reputation: 27542

The point of the article is that it is possible to have multiple timers trigger the same handler but you need to differentiate them based on some passed data. Oddly the example the author used only went 3/4th of the distance of illustrating this in the code so maybe that is the source of your confusion.

Hopefully this reworking of the article's program is a bit clearer. It uses the sival_ptr to point to a string but it can point to any type. This is how the timers are differentiated.

#define _POSIX_C_SOURCE 199309
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

void timerHandler( int sig, siginfo_t *si, void *uc )
{
    // obligator caution not to use printf and other async-unsafe calls
    // in a handler in real programs

    printf("I am timer %s\n", (char *) si->si_value.sival_ptr);
}

void makeTimer(char *name, int intervalMS)
{
    struct sigevent         te;
    struct itimerspec       its;
    struct sigaction        sa;
    int                     sigNo = SIGRTMIN;

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

    if (sigaction(sigNo, &sa, NULL) == -1)
        errExit("sigaction");

    // Set up timer
    te.sigev_notify = SIGEV_SIGNAL;
    te.sigev_signo = sigNo;
    te.sigev_value.sival_ptr = name;

    timer_t timerID;

    if (timer_create(CLOCK_REALTIME, &te, &timerID) == -1)
        errExit("timer_create");

    its.it_value.tv_sec = intervalMS;
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = 0;

    if (timer_settime(timerID, 0, &its, NULL) == -1)
        errExit("timer_settime");

    return;
}

int main(int argc, char *argv[])
{
    char *arr[3] = {"number one", "number two", "number three"};

    makeTimer(arr[0], 1);
    makeTimer(arr[1], 2);
    makeTimer(arr[2], 3);

    while (sleep(5));

    return(0);
}

Upvotes: 2

abligh
abligh

Reputation: 25119

There is no reason you can't have multiple timers created with timer_create using the same handler, provided your sigval structure contains enough information to distinguish between them as needed in your handler.

Upvotes: 2

Related Questions