Documentation

Documentation.Development-Manual-API-Timer-3-3 History

Hide minor edits - Show changes to markup

December 11, 2019, at 06:57 PM by liviu -
Changed line 16 from:

OpenSIPS exposes it's own API for implementing timer functions, with seconds and microsecond precision.\\

to:

OpenSIPS exposes its own API for implementing timer functions, with seconds and microsecond precision.\\

December 11, 2019, at 06:57 PM by liviu -
Added lines 1-141:
Documentation -> Development Manual 3.3 -> Timer API

This page has been visited 426 times. (:title OpenSIPS Development - Timer API:)


(:allVersions Development-Manual-API-Timer 3.3:)


Timer API

(:toc-float Table of Content:)

OpenSIPS exposes it's own API for implementing timer functions, with seconds and microsecond precision.
The OpenSIPS timer architecture is made out of the so called 'timer keeper' , which is a process which just increments global counter of second and microsecond precision, and one process which will execute the various timer functions when their time to execute has arrived.
Also, the OpenSIPS timers support automatic re-calibration in order to compensate timer drifting in case the timer executed functions do not complete in timely manners.

Global Timer Process

timer.h exposes all the relevant functionalities for operating the OpenSIPS timers. For registering a new timer function with second precision, use : (:source lang=C -link -getcode :) /* 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); (:sourceend:)
For registering a microsecond timer, you should use (:source lang=C -link -getcode :) /* 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); (:sourceend:)

Dedicated Timer Process

Since, 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.
Registering a new timer process can be done by calling :

(:source lang=C -link -getcode :) /* 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);

(:sourceend:)
The output struct sr_timer_process pointer can be further use to group together multiple functions inside the same process, by calling : (:source lang=C -link -getcode :) /* 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);

(:sourceend:)

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 : (:source lang=C -link -getcode :) 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; 
      } 

} (:sourceend:)
Also, the OpenSIPS API also exposes the number of seconds and microseconds passed from the OpenSIPS start time. These can be accessed by calling (:source lang=C -link -getcode :) /* 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); (:sourceend:)


Page last modified on December 11, 2019, at 06:57 PM