Libev中的超时监视器ev_periodic,是绝对时间定时器,不同于ev_timer,它是基于日历时间的。比如如果指定一个ev_periodic在10秒之后触发(ev_now() + 10),然后将系统时间调整为去年的一月一号,则该定时器会在一年后才触发超时事件。(ev_timer依然会在10秒之后触发)
一:数据结构
超时监视器ev_ periodic结构:
typedef struct ev_periodic
{
int active;
int pending;
int priority;
void *data;
void (*cb)(struct ev_loop *loop, struct ev_periodic *w, int revents);
ev_tstamp at;
ev_tstamp offset; /* rw */
ev_tstamp interval; /* rw */
ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
} ev_periodic;
可见其中的前六个成员与ev_timer和ev_watcher_time是一样的。与ev_timer类似,ev_periodic中的active也标明该监视器在堆数组periodics中的下标;at表明超时事件触发的时间点,共有三种设置方法,而且offset、interval和reschedule_cb都是用来设置触发时间的,这个会在下面说明。
二:监视器函数
1:设置超时监视器
#define ev_periodic_set(ev,ofs_,ival_,rcb_) do {\
(ev)->offset = (ofs_); \
(ev)->interval = (ival_); \
(ev)->reschedule_cb = (rcb_); \
}while (0)
#define ev_periodic_init(ev,cb,ofs,ival,rcb) do {\
ev_init ((ev), (cb)); \
ev_periodic_set ((ev),(ofs),(ival),(rcb)); \
} while (0)
2:启动监视器ev_periodic_start
void ev_periodic_start (struct ev_loop *loop, ev_periodic *w)
{
if (expect_false (ev_is_active (w)))
return;
if (w->reschedule_cb)
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
else if (w->interval)
{
assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
periodic_recalc (EV_A_ w);
}
else
ev_at (w) = w->offset;
++periodiccnt;
ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
array_needsize (ANHE, periodics, periodicmax,