目录
libhv提供的事件除了支持定时器事件和I/O事件之外,还额外提供了idle事件.初看idle事件,根据字面意思:"空闲的"可得,这个事件指的是当libhv事件回环中没有其他事件(定时器或者I/O事件)可以执行时才会去执行的事件.
一 idle事件的创建:
hidle_add函数的用途是:
1.在堆区创建一个idle类型的节点(赋予事件类型为空闲事件类型,事件优先级为最低优先级,空闲事件重复触发次数为repeat);
2.将idle节点node加入loop的idles链表中(具体方法见上一篇:libhv学习路线 之 list.h);
3.调用EVENT_ADD()设置激活idle事件并且设置回调函数cb.
hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat) {
hidle_t* idle;
HV_ALLOC_SIZEOF(idle);
idle->event_type = HEVENT_TYPE_IDLE;
idle->priority = HEVENT_LOWEST_PRIORITY;
idle->repeat = repeat;
list_add(&idle->node, &loop->idles);
EVENT_ADD(loop, idle, cb);
loop->nidles++;
return idle;
}
二 idle事件的处理
idle事件是在hloop_process_events()函数中进行处理的.该函数具体代码分析在之后再进行讲述,在此我们只分析有关于idle事件处理的部分:
int npendings = loop->npendings;//获取loop回环中待处理事件个数
if (npendings == 0) {//当事件回环中没有待处理事件时
if (loop->nidles) {
nidles= hloop_process_idles(loop);//调用函数将idle事件一个一个加入待处理事件集合
}
}
hloop_process_events()对于idle事件的处理是在待处理事件集合中没有其他事件时才会调用hloop_process_idles()函数来将待处理的idle事件加入待处理事件集合中:
static int hloop_process_idles(hloop_t* loop) {
int nidles = 0;
struct list_node* node = loop->idles.next;
hidle_t* idle = NULL;
while (node != &loop->idles) {//在idles链表中依次寻找idle事件直到查找到idles头节点为止
idle = IDLE_ENTRY(node);//获取当前节点对应的idle事件
node = node->next;//遍历下一个节点
if (idle->repeat != INFINITE) {
--idle->repeat;
}
if (idle->repeat == 0) {
__hidle_del(idle);//当idle事件的循环次数为0时,调用__hidle_del()函数,将idle->destroy设为1
//但是暂时不调用EVENT_DEL()销毁事件
}
EVENT_PENDING(idle);//将当前idle事件加入待处理事件队列中
++nidles;
}
return nidles;
}
最后,在hloop_process_events()函数的末尾调用hloop_process_pendings()函数对待处理事件集合中的所有事件进行处理(执行响应回调函数).
三.idle事件的销毁
idle事件的销毁有两种方法:1.循环调用hloop_process_events()函数 ,直到idle事件重复加入待处理集合并且处理完repeat次为止;2.调用hidle_del()函数手动删除本idle事件.
static void __hidle_del(hidle_t* idle) {
if (idle->destroy) return;
idle->destroy = 1; //设置销毁标志
list_del(&idle->node); //从链表中删除
idle->loop->nidles--; //空闲事件减1
}
void hidle_del(hidle_t* idle) {
if (!idle->active) return;
EVENT_DEL(idle);
__hidle_del(idle);
}
四.idle事件执行顺序
1.利用idle_add()函数创建idle事件:设置idle回调函数,重复次数,将idle事件加入idles链表中;
2.调用hloop_process_events()函数处理idle事件:
a.调用hloop_process_idles()函数将循环遍历idles链表将idle事件加入待处理事件集合;
b.调用hloop_process_pendings()函数处理待处理事件集合中的事件;
3.选择性执行hidle_del()函数删除不需要且重复次数还未完成的idle事件.