Timer API

API Reference


This module provides an API for managing and using timers.

Note
This is an initial version of the API that only provides support for relative timers (e.g., expires in 10 seconds). Absolute timers allow a specific time/date to be used, and will be supported in a future version of this API.

Creating/Deleting Timer Objects

Timers are created using le_timer_Create(). The timer name is used for diagnostic purposes only.

The following attributes of the timer can be set:

The following attributes of the timer can be retrieved:

The repeat count defaults to 1, so that the timer is initially a one-shot timer. All the other attributes must be explicitly set. At a minimum, the interval must be set before the timer can be used. Note that these attributes can only be set if the timer is not currently running; otherwise, an error will be returned.

Timers must be explicitly deleted using le_timer_Delete(). If the timer is currently running, it'll be stopped before being deleted. If a timer uses le_timer_SetContextPtr(), and the context pointer is allocated memory, then the context pointer must be freed when deleting the timer. The following function can be used for this:

static void DeleteTimerAndFreePtr(le_timer_Ref_t t)
{
free( le_timer_GetContextPtr( t ) );
le_timer_Delete( t ); // timer ref is now invalid
}

You can call this function anywhere, including in the timer handler.

Using Timers

A timer is started using le_timer_Start(). If it's already running, then it won't be modified; instead an error will be returned. To restart a currently running timer, use le_timer_Restart().

A timer is stopped using le_timer_Stop(). If it's not currently running, an error will be returned, and nothing more will be done.

To determine if the timer is currently running, use le_timer_IsRunning().

To find out how much time is remaining before the next expiry, call either le_timer_GetTimeRemaining() or le_timer_GetMsTimeRemaining().

When a timer expires, if the timer expiry handler is set by le_timer_SetHandler(), the handler will be called with a reference to the expired timer. If additional data is required in the handler, le_timer_SetContextPtr() can be used to set the appropriate context before starting the timer, and le_timer_GetContextPtr() can be used to retrieve the context while in the handler. In addition, a suspended system will also wake up by default if the timer expires. If this behaviour is not desired, user can disable the wake up by passing false into le_timer_SetWakeup().

The number of times that a timer has expired can be retrieved by le_timer_GetExpiryCount(). This count is independent of whether there is an expiry handler for the timer.

Thread Support

A timer should only be used by the thread that created it. It's not safe for a thread to use or manipulate a timer that belongs to another thread. The timer expiry handler is called by the event loop of the thread that starts the timer.

The call to the timer expiry handler may not occur immediately after the timer expires, depending on which other functions are called from the event loop. The amount of delay is entirely dependent on other work done in the event loop. For a repeating timer, if this delay is longer than the timer period, one or more timer expiries may be dropped. To reduce the likelihood of dropped expiries, the combined execution time of all handlers called from the event loop should ideally be less than the timer period.

See Event Loop API for details on running the event loop of a thread.

Suspend Support

The timer runs even when system is suspended.
If the timer expires while the system is suspended, it will wake up the system.

Fatal Errors

The process will exit under any of the following conditions:

Troubleshooting

Timers can be traced by enabling the log trace keyword "timers" in the "framework" component.

See Log Controls for more information.