简体   繁体   中英

Passing user data with timer_create

I am using timer_create to create a timer in Linux. The callback prototype is:

static void TimerHandlerCB(int sig, siginfo_t *extra, void *cruft)

How can i pass user data so that i can receive the same in the callback called after timer expiry.

Here's my sample code:

int RegisterTimer(iDiffInTime)
{
    struct sigaction sa; 
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO;   /*call our handler*/
    sa.sa_sigaction = TimerHandlerCB;/*Event handler to be called after timer expires*/ 
    if(sigaction(SIGRTMAX, &sa, NULL) < 0)
    {
        perror("sigaction");
        return 1;
    }
    // Setup the timer
    sigevent sigev;
    timer_t timerid = 0;

    memset(&sigev, 0, sizeof(sigev));

    sigev.sigev_notify          = SIGEV_SIGNAL;
    sigev.sigev_signo           = SIGRTMAX;
    sigev.sigev_value.sival_ptr = &timerid;

    timer_t timerid;

    if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0)
    {
        printf("Timer created\n");
        struct itimerspec itval, oitval;

        itval.it_value.tv_sec = iDiffInTime * 1000;
        itval.it_value.tv_nsec = 0;
        itval.it_interval.tv_sec = 0;
        itval.it_interval.tv_nsec = 0;

              //Populate handles required in TimerCallback
              Display_Handle hDisplay = ......//
              Buffer_Handle hBuf = .....//
        if (timer_settime(timerid, 0, &itval, &oitval) != 0)
        {
            perror("time_settime error!");
            return 1;
        }
    } 
    else 
    {
        perror("timer_create error!");
    }
    return 0
}

Where do I pass hDisplay & hBuf so that I can receive them back in TimerHandlerCB ?

You are already doing it:

sigev.sigev_value.sival_ptr = &timerid;

You can specify anything in there (specifying &timerid is common to discern between multiple timers but is not required). Now in your handler:

static void timer_handler(int signo, siginfo_t *si, void *uc)
{
    /* si->si_value.sival_ptr */
}

Quote from TLPI

When calling timer_create(), evp.sigev_value.sival_ptr is typically assigned the address of the timerid argument given in the same call. Alternatively, evp.sigev_value.sival_ptr may be assigned the address of a structure that contains the timerid given to timer_create()

You need to either :

  • add global variable and use some synchronization mechanism like semaphores
  • use sigqueue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM