Files
2016-03-19 18:57:49 +01:00

162 lines
5.0 KiB
C

#ifndef UC_TIMERS_H_
#define UC_TIMERS_H_
#include <stddef.h>
#include <sys/queue.h>
#include <sys/time.h>
#include "rbtree.h"
/** @addtogroup Timers
* @{
* Timer management for managing timeouts
*/
#ifdef __cplusplus
extern "C" {
#endif
struct UCTimer;
struct UCTimers;
struct UCoreClock;
//internal timer states
enum {
//not running
UC_TIMER_INACTIVE = 0,
//running
UC_TIMER_ACTIVE = 1,
//running and pending to be fired in this run of uc_timers_run
UC_TIMER_PENDING = 2
};
/** Callback function which is called when the timer fires.
* @param timers timer engine
* @param the timer that fired
*/
typedef void (*uc_timer_cb)(struct UCTimers *timers, struct UCTimer *timer);
/** Timer struct. The internal members must not be messed with, and must
* be zeroed out before using/adding a timer for the first time.
*
* The external members are user controllable, the calback member must be set
* and the cookie members can be used to stuff away things that's handy to use
* in the callback function
*/
struct UCTimer {
//Internal members
RBNode rb_node; //the RBNode will hold a data pointer to the
//the UCTimer it's a member of. We might get rid of that
//member, and use CONTAINER_OF to find the UCTimer from
//a RBNode (Or just cast it, it's the 1. member..)
//absolute time when the timer should be fired
struct timeval timeout;
size_t seq; //needed to keep timeout unique
//as the rbtree can only handle unique values
unsigned char state;
TAILQ_ENTRY(UCTimer) ready_entry; //entry in ready_list in UCTimers
//External members
//callback function
uc_timer_cb callback;
//user data for the callback
void *cookie_ptr;
int cookie_int;
int cookie_int2;
};
/** Timer engine. Must be initialized onnce.*/
struct UCTimers {
RBTree timer_tree;
struct UCoreClock *uclock;
size_t seq; //used to generate unique timers
TAILQ_HEAD(, UCTimer) ready_list; //pending timers to be fired while
//inside uc_timers_run
};
/** Initialize a timer engine for use.
* An UCTimers can be accessed in only one thread.
*
* @param t UCTimers struct to initialize
*/
void uc_timers_init(struct UCTimers *t);
/** Initialize a timer engine for use, with a user supplied clock.
*
* @param t UCTimers struct to initialize
*/
void uc_timers_init_ex(struct UCTimers *t, struct UCoreClock *uclock);
/** Add a (one-shot) timer to the timer engine.
* User fills in the callback and any cookie members of the UCTimer. The callback
* will be called when the timer expires, and the timer is removed from the engine
* User is responsible for the lifetime and memory of the UCTimer, which must exist until
* te timer is fired or removed.
* If the timer has previously been added, it will be removed first. So there
* is no need to call uc_timers_remove() to "re-schedule" a timer.
*
* @param timers timer engine to add timer to.
* @param timer timer to add
* @param sec seconds from now until the timer filres
* @param usec microseconds (after the @sec) until the timer fires.
*/
void uc_timers_add(struct UCTimers *timers, struct UCTimer *timer, int sec, int usec);
/** Remove a timer.
* Note, the timer memory must have been zeroed out or the timer must have been
* added at least once before uc_timers_remove can be called on a UCTimer.
* uc_timers_remove does nothing if the timer has expired.
*
* @param timers timer engine to remove from
* @param timer timer to remove
*/
void uc_timers_remove(struct UCTimers *timers, struct UCTimer *timer);
/** Get time of the first timer that will run.
*
* @param timers timer engine to query.
* @param first output parameter filled in with the expiry time of the first timer.
* @return 0 on success and @first is filled in. non-0 if there's no pending timers.
*/
int uc_timers_first(const struct UCTimers *timers, struct timeval *first);
/** Get the number of timers the engine is tracking.
* (This function is O(n) )
*
* @param timers timer engine to query
* @return the number of timers the engine keeps
*/
size_t uc_timers_count(const struct UCTimers *timers);
/** Check if a timer is running (i.e. hasn't expired and fired)
*
* @param timer timer to query
* @return 0 if the timer has expired (or was never added) non-0 if it's
* running (active or pending)
*/
int uc_timer_running(const struct UCTimer *timer);
/** Run one iteration of the timer engine, firing off any expired timers.
* Typically this is called once in an event loop.
*
* @param timers timer engine to run
* @param now The curent time. The engine will fire all timers whose expiry time is
* prior to this value.
* @return the number of timers fired, or negative if an error occured(presently
* no errors are possible and the return value is always >= 0
**/
int uc_timers_run(struct UCTimers *timers);
//uc_timers_destroy(struct UCTimers *timers) is currently missing..
#ifdef __cplusplus
}
#endif
/** @} (addtogroup) */
#endif