(v13) Setting up a timed callback
This page applies to Harlequin v13.1r0 and later; and to Harlequin MultiRIP but not Harlequin Core
A timed callback is created by calling the function hqn_timer_create
(). This is the typedef and prototype for this function:
typedef void (HQNCALL hqn_timer_callback_fn) (hqn_timer_t *timer, void *data);
hqn_timer_t *(HQNCALL
*hqn_timer_create)( unsigned int first, unsigned int repeat,
hqn_timer_callback_fn *callback, void *data);
The first two arguments define the time, in milliseconds, before the function is first called, and then between each subsequent call. If the time before the function is first called is zero, the function will be called as soon as the timer has been successfully set up. If the time between repeated calls is zero, the function is only called once, after the delay before the first call.
NOTE: A repeat time of less than 20ms is not recommended. At these short periods the operating system's scheduler time quanta becomes significant and the time between calls could vary considerably compared to that requested.
The third argument is the pointer to the function that will be called by the timer library. This function takes two arguments, the handle of the timer that caused the function to be called, and void pointer. The void pointer is a copy of the void pointer that is the fourth argument to hqn_create_timer
() which allows you to pass through any data you want to the function when it is called.
If the library successfully creates the timer, it will return a non-NULL timer handle. This handle should be remembered so that the timer can later be destroyed (see Terminating a timed callback
The following is an example of how to set up a timer callback function to prevent a communications channel connection from timing out:
#include "timerapi.h"
/* Data identifying a communications channel connection to keep active. */
struct COMMS_CHANNEL {
...
};
/* Timer callback to use a comms channel connection to keep it alive
*/
void HQNCALL keep_alive_ping( hqn_time_t *timer,
void* data)
{
struct COMMS_CHANNEL* p_comms_channel = data;
...
}
struct COMMS_CHANNEL comms_channel; hqn_timer_t *keep_alive_timer;
void setup_keep_alive_ping(void)
{
unsigned int ping_delay = 60*1000;
...
comms_channel = ...;
keep_alive_timer = hqn_create_timer(0, ping_delay, keep_alive_ping,
&comms_channel);
...
}
Once the timer has been created the callback function is called at the requested period. The callback function should take no longer than the repeat time to complete, or it should be tolerant of time delays longer than its requested repeat period. If the callback function has not returned by the end of the repeat period, the library will not call the function again but will wait until the end of the next repeat period missed calls are not queued up to be called when the function finally returns.
Timer callback functions are always called in a separate thread. Timers with non-zero repeat times are not guaranteed to call the function in the same separate thread each time. Callback functions that use data shared with other threads will need to use the usual thread synchronization methods.