Documentation |
Documentation -> Development Manual -> Timer APIThis page has been visited 198 times.
Table of Content (hide) OpenSIPS exposes its own API for implementing timer functions, with seconds and microsecond precision. 1. Global Timer Processtimer.h exposes all the relevant functionalities for operating the OpenSIPS timers. For registering a new timer function with second precision, use : /* Parameters : label – opaque string containing a short timer function description ( to be used for logging ) f – the actual function to be called param – parameter to be provided to the timer function interval – the interval, in seconds, that the function needs to be called at Returns : 0 in case of success, negative code in case of internal error. */ int register_timer(char *label, timer_function f, void* param, unsigned int interval); /* The seconds callback Parameters : ticks - represents the current number of seconds since OpenSIPS startup when the callback is called at param - is the parameter provided at timer function registration. */ typedef void (timer_function)(unsigned int ticks, void* param);
/* Parameters : label – opaque string containing a short timer function description ( to be used for logging ) f – the actual function to be called param – parameter to be provided to the timer function interval – the interval, in microseconds, that the function needs to be called at Returns : 0 in case of success, negative code in case of internal error. */ int register_utimer(char *label, utimer_function f, void* param, unsigned int interval); 2. Dedicated Timer ProcessSince, by default, all the registered timer functions are called from within the same process context, in case you are writing a timer process that is doing I/O, it is better to register an entirely new process where to run your code, since your function might slow down all the other timer functions running in OpenSIPS. /* Parameters : label - opaque string containing a short timer function description ( to be used for logging ) f - the actual function to be called param - parameter to be provided to the timer function interval - the interval, in seconds, that the function needs to be called at flags - flags controlling process behavior. Currently only option is TIMER_PROC_INIT_FLAG , which leads to child_init to be called in the new timer process context. To be used when inside the timer you need to operate various I/O options which generally require a per process connection. Returns : struct sr_timer_process pointer in case of success, or NULL in case of error. */ void* register_timer_process(char *label, timer_function f, void* param, unsigned int interval, unsigned int flags);
/* Parameters: label – opaque string containing a short timer function description ( to be used for logging ) f – the actual function to be called param – parameter to be provided to the timer function interval – the interval, in seconds, that the function needs to be called at timer – the struct sr_timer_process pointer obtained by previously calling register_timer_process Returns: 0 in case of success, negative code in case of internal error. */ int append_timer_to_process( char *label, timer_function f, void* param, unsigned int interval, void *timer);
Important to note here that all the above timer related functions MUST be called in the context of the attendant process before forking is done ( so either from the modules mod_init or directly from the core, before forking ). Below is a code snippet exemplifying how the dialog module's code used for registering two timers, with an option to either use the global timer process or to have it's own separate timer : if (dlg_have_own_timer_proc) { LM_INFO("Running with dedicated dialog timer process\n"); dlg_own_timer_proc = register_timer_process( "dlg-timer", dlg_timer_routine, NULL,1,TIMER_PROC_INIT_FLAG ); if (dlg_own_timer_proc == NULL) { LM_ERR("Failed to init dialog own timer proc\n"); return -1; } if (append_timer_to_process("dlg-pinger", dlg_ping_routine, NULL, ping_interval,dlg_own_timer_proc) < 0) { LM_ERR("Failed to append ping timer \n"); return -1; } } else { if ( register_timer( "dlg-timer", dlg_timer_routine, NULL, 1)<0 ) { LM_ERR("failed to register timer \n"); return -1; } if ( register_timer( "dlg-pinger", dlg_ping_routine, NULL, ping_interval)<0) { LM_ERR("failed to register timer 2 \n"); return -1; } }
/* Returns : the number of seconds elapsed from OpenSIPS start */ unsigned int get_ticks(void); /* Returns: the number of microseconds elapsed from OpenSIPS start */ utime_t get_uticks(void); |