1

I am trying to implement a callback timer function in C++ which should do a callback after a timeout. I am listening on a socket and then waiting for messages on it. so if I have something like getMessages() and I want to pass the timer function in it as an argument. So how can it be implemented that after the receive of a message, the timer is started and the callback happens if there is a timeout before the next messages arrives.

I am new to callback functions. Any help is greatly appreciated. Thanks!

user3596609
  • 11
  • 1
  • 3

2 Answers2

1

You probably know, but there are no such things as callback functions in C++. There are, however, function pointers.

Function pointers are literally that - pointers to functions. With "normal" pointers you specify the data type that the pointer points to (e.g. int *foo, char *bar...); function pointers work similarly in that you specify the signature of the function: void (*baz)(int). Notice that baz is the name of the pointer in this case.

Without code I'm not sure how your timing system will work. The first thing that would come to mind would be a tick function which is called repeatedly. You can either call this function at regular intervals or measure the time between the function calls - in either case you know the time that has elapsed. Increment (or decrement) an allotted time variable, and when the time is up use the function pointer to trigger the "callback".

One thing you may find useful is typedefing your callback function like so: typedef void (*Callback)(int) (again, Callback is the identifier). Then you can define a function like any other member (Callback func = foo) and call it (func(12)).

PS: There are good resources for function pointers dotted around SE. Here's one.

Community
  • 1
  • 1
Sean Latham
  • 250
  • 1
  • 12
0
    Here is one approach that I would suggest. You will require 3 different threads for this:

 1. First thread is the main processing thread (Th1). It waits for two separate events - either "data on socket" event or "timeout event"
 2. Second thread (Th2) will constantly listen on socket ( stay blocked on socket either through select or read call ) and when data appears it will read the data, wrap the data in an event and post it to the first thread.
 3. The third thread (Th3) will implement the timer functionality. It will wake up after every 'N' seconds ( where 'N'is timeout interval ) and once it wakes up it will create a timeout event and post it to first thread.

    A skeleton of the code would look something like this:

    Class Processor
    {
      public:
        // std::list<ProcessorEventBase* > eventQueue;
        void init ()
        {
            // 1. initialize SocketListener and pass address of 'Processor::recvDataOnSocket' function
            // 2. initialize TimerUtil and pass address of 'Processor::timeOut' function
            // 3. create and run Processor ( Th1 ) thread
            // 4. keep the thread waiting on a condition variable
            // 5. When thread wakes up, let it fetch event from queue and process it.
        }

        static void recvDataOnSocket ( char* data, int datalen, void* arg )
        {
           // typecast arg to Processor
           // create a data on socket event
           // post it to the 'eventQueue'
           // signal the waiting thread
        }

        static void timeOut ( void* arg )
        {
            // typecast arg to Processor
            // create a timeout event
            // post it to event queue
            // signal the waiting thread
        }    
    }

    class SocketListener
    {
       public:
          void init ( SocketCallback socketCallback)
           {
               // store the socket Callback
               // create a thread to listen on socket ( Th2 )
               // when data arrives, call the callback i.e. socketCallback and 
               // pass data pointer and its size and the stored arguement
           }
    }

    class TimerUtil
    {
       public:
          void init ( TimeoutCallback timeoutCallback, void* arg )
           {
               // store the timeout Callback
               // create a thread that wakes up every 'N' seconds ( Th3 )
               // when timer expires, call the callback i.e. timeoutCallback and 
               // pass the stored argument i.e. arg
           }
    }

Callback would be something like this:

    typedef void (*SocketCallback ) ( char* data, int datalen, void* arg);
    typedef void (*TimeoutCallback ) ( void* arg );
Vimal
  • 436
  • 1
  • 4
  • 14