1.Ring的定义
typedef struct Ring RingItem;
typedef struct Ring {
RingItem *prev;
RingItem *next;
} Ring;
2.SpiceTimer的定义
typedef struct SpiceTimer {
RingItem link;
SpiceTimerFunc func;
struct timeval tv_start;
int ms;
void *opaque;
} Timer;
Ring timers;
(1)双向链表元素link 用来将多个定时器连接成双向循环队列,link是作为一个类似句柄或指针的东西挂载到了 Ring环中,可以利用宏通过link来获取timer结构。
(2)函数指针func指向一个可执行函数 当定时器到期时,会执行这个函数
(3)tv_start就是定时开始的时间
(4)ms就是要定时的时间长度
(5)opaque应该是其他的信息
3.添加一个定时器
static SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque)
{
SpiceTimer *timer = calloc(sizeof(SpiceTimer), 1); //为定时器申请内存地址
timer->func = func; //注册定时器调用的函数
timer->opaque = opaque; // 传入opgue参数
ring_add(&timers, &timer->link); //将定时器添加到timers环中
return timer; // 返回定时器指针
}
4.启动一个定时器
static void timer_start(SpiceTimer *timer, uint32_t ms)
{
ASSERT(ms); //断言ms是0吗,不是继续运行,是的话直接退出该函数
gettimeofday(&timer->tv_start, NULL); //得到当前的精准时间,放入tv_start
timer->ms = ms; //将定时器等待的时间ms赋值给timer->ms
// already add ms to timer value
add_ms_to_timeval(&timer->tv_start, ms); //当前时间加上ms,这样tv_start存储定时器到点的那刻
}
5.取消一个定时器
static void timer_cancel(SpiceTimer *timer)
{
timer->ms = 0; //将定时器的时间ms赋值为0
}
6.删除一个定时器
static void timer_remove(SpiceTimer *timer)
{
ring_remove(&timer->link); //从定时器环中删除
}
7.总结
由于spice 中定时器机制用的比较频繁,所以代码阅读起来相对来说有点难度,其实只要我们抓住定时器机制的要点,那么就会对代码中的很多地方函数的调用有一个清晰的了解,首先如果一个函数要使用定时器机制的话,那么它会作为定时器func函数利用 timer_add函数添加到定时器环中,其次会设置定时器的定时时间,启动这个定时器,直到时间到达之后,这个func函数才会执行。 也就是说不要看到这个函数在这个地方他就会执行,也许它只是出来和你见个面打个招呼而已。