c++ timer implemetation - Assigning a member function to signal callback function pointer

-1

hi i have been tryng to implement a timer using posix timer libs, but i am making a mistake in the implemetation, i was using a example from the web and tryng to encapsulating in a class but, the compiler doesnt like it, basically tryng to asign the callback function int the sigev.sigev_notify_function = TIMER0_IRQHandler; but i cannot get any result. Here goes the code:

The class definition:

#include <sys/time.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
//se agrego para eliminar el siguiente warning del compilador
//warning: incompatible implicit declaration of built-in function 'memset'
#include <string.h> /* memset */
#include <unistd.h> /* close */


#define TIMEVAL_MAX 0xFFFFFFFF
#define TIMEVAL unsigned int
// The timer is incrementing every 4 us.
//#define MS_TO_TIMEVAL(ms) (ms * 250)
//#define US_TO_TIMEVAL(us) (us>>2)

// The timer is incrementing every 8 us.
#define MS_TO_TIMEVAL(ms) ((ms) * 125)
#define US_TO_TIMEVAL(us) ((us)>>3)

class Timer
{
public:
    Timer();
    void initTimer();
    void setTimer(TIMEVAL aValue);
    TIMEVAL getElapsedTime( void ) ;
    void TIMER0_IRQHandler(sigval_t val);
private:
    struct timeval last_sig;
    timer_t timer;

};

and the function that is conflicting with the compiler:

void Timer::initTimer()
{
        struct sigevent sigev;

        // Take first absolute time ref.
        if(gettimeofday(&last_sig,NULL)){
            perror("gettimeofday()");
        }

        memset (&sigev, 0, sizeof (struct sigevent));
        sigev.sigev_value.sival_int = 0;
        sigev.sigev_notify = SIGEV_THREAD;
        sigev.sigev_notify_attributes = NULL;
        sigev.sigev_notify_function = &TIMER0_IRQHandler;

        if( timer_create (CLOCK_REALTIME, &sigev, &timer)) {
            perror("timer_create()");
        }

}
*//callback function
void Timer::TIMER0_IRQHandler(sigval_t val)
{
    if(gettimeofday(&last_sig,NULL)) {
        perror("gettimeofday()");
    }
    printf("TIMER NOTIFY\n");
}

thx in advance!

c++
linux
timer
asked on Stack Overflow Aug 7, 2013 by Ricardo_arg

2 Answers

1

To call a member function, you also need the pointer to this, which means you can't do this directly. You can, however, use a static function as a wrapper for your callback, which can extract the this pointer and call your real callback:

class Timer
{
public:
    static void handler_wrapper(sigval_t val);
    void handler();
};

void Timer::handler_wrapper(sigval_t val)
{
    Timer *object = (Timer *)val.sival_ptr;
    object->handler();
}

void Timer::handler(void)
{
    // do whatever.  just remember what thread context you're in
}

// in main
sigev.sigev_value.sival_ptr = (void*) this;
sigev.sigev_notify_function = &Timer::handler_wrapper;
answered on Stack Overflow Aug 7, 2013 by Peter
0

You can use std::bind to create a function object to pass non-static member functions to be invoked at the end of timer(or timeout).

std::bind(&class_name::mem_func, obj_ptr, args_list ...);

The drawback with this is similar to static member functions, i.e. the thread does not have context of the parent object, although you might be able to run the member function stand-alone (if it doesn't use any parent object attributes). Which is pretty much the same as with static member function, which requires member attributes of the class to be static in case they are required/accessed/used by it.

Note: Pass the object reference (using std::ref) or pointer in arguments and use it in your member function.

answered on Stack Overflow Dec 10, 2019 by user3301096 • edited Dec 10, 2019 by Adrian Mole

User contributions licensed under CC BY-SA 3.0