int
event_loopbreak(void)
{
return (event_base_loopbreak(current_base));
}
int
event_base_loopbreak(struct event_base *event_base)
{
if (event_base == NULL)
return (-1);
event_base->event_break = 1;
return (0);
}
event_loopbreak
就是直接设置event_base
中的event_break
退出标记.
int
event_base_loopexit(struct event_base *event_base, const struct timeval *tv)
{
return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb,
event_base, tv));
}
哦豁, 又与到了没有见到过大函数event_base_once
函数, 不急慢慢来分析.
先来看一下event_once
结构
struct event_once {
struct event ev; // 事件
// 回调函数
void (*cb)(int, short, void *);
void *arg; // 回调函数第三个参数
};
/* Schedules an event once */
// 设置一次性的事件回调, 当该事件执行后便删除不再执行
int
event_base_once(struct event_base *base, int fd, short events,
void (*callback)(int, short, void *), void *arg, const struct timeval *tv)
{
struct event_once *eonce;
struct timeval etv;
int res;
/* We cannot support signals that just fire once */
// 不支持信号
if (events & EV_SIGNAL)
return (-1);
// 申请空间
if ((eonce = calloc(1, sizeof(struct event_once))) == NULL)
return (-1);
eonce->cb = callback;
eonce->arg = arg;
if (events == EV_TIMEOUT) {
if (tv == NULL) {
evutil_timerclear(&etv);
tv = &etv;
}
evtimer_set(&eonce->ev, event_once_cb, eonce);
} else if (events & (EV_READ|EV_WRITE)) {
events &= EV_READ|EV_WRITE;
// 初始化事件, 并设置事件的回调函数都设置为 event_once_cb
event_set(&eonce->ev, fd, events, event_once_cb, eonce);
} else {
/* Bad event combination */
free(eonce);
return (-1);
}
// 重新设置该事件
res = event_base_set(base, &eonce->ev);
if (res == 0)
// 将时间设置定时
res = event_add(&eonce->ev, tv);
if (res != 0) {
free(eonce);
return (res);
}
return (0);
}
event_base_once
其实就是重新设置了一个eonce
结构并初始化了结构中的event
事件, 默认回调函数设置成event_once_cb
, 接着调用event_base_set
重新设置事件的反应器(base).
其中涉及到的event_set
, event_base_set
和event_add
在前面都已经分析过了, 忘了可以重新看一下.
/* One-time callback, it deletes itself */
// event_base_once 默认设置的回调函数
static void
event_once_cb(int fd, short events, void *arg)
{
struct event_once *eonce = arg;
// 调用事件的回调函数
(*eonce->cb)(fd, events, eonce->arg);
free(eonce);
}
static void
event_loopexit_cb(int fd, short what, void *arg)
{
struct event_base *base = arg;
base->event_gotterm = 1;
}
然后event_once_cb
回调函数调用后还是调用事件本身注册的一个回调函数.
event_base_loopexit
函数告诉event_base
在给定时间后停止循环. 如果tv参数为NULL, 则event_base
会在没有延迟的情况下停止循环. 如果主循环现在正在执行回调, 则主循环将继续运行回调直到全部运行完后才执行退出.
event_base_loopbreak
函数告诉event_base
立即退出主循环. 它与event_base_loopexit(base,NULL)
的不同之处在于. 如果主循环当前正在执行回调, 则执行完当前的回调之后就立即退出, 不再执行剩余就绪的事件.
当没有运行事件循环时event_base_loopexit(base,NULL)
和event_base_loopbreak(base)
的行为会有所不同 : loopexit
会调度事件循环的下一个实例, 以便在运行下一轮回调后立即而loopbreak
仅停止当前正在运行的循环, 并且如果主循环未运行则无效.
event_base_loopexit
让主循环在给定时间之后停止循环. 如果tv参数为NULL, 主循环会执行完所有就绪事件之后退出.event_base_loopbreak
立刻退出主循环.