event 非正常退出主循环

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Function_Dou/article/details/87891384

event_loopbreak 函数

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退出标记.

event_base_loopexit 函数

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_setevent_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_once_cb后会感到很绕, 其实说白了就是调用了两次回调函数, 一次是重新注册的event_once_cb回调函数, 然后在调用事件本身的处理回调函数, 最后调用event_loopexit_cbevent_gotterm设置为1, 退出主循环.

哇, 说了这么一大堆你肯定不怎么懂, 如果想要真的了解这个的可以画一下理解. 不懂的话就看我现在总结的.

总结

  1. event_base_loopexit 让主循环在给定时间之后停止循环. 如果tv参数为NULL, 主循环会立即退出.
  2. event_base_loopbreak 立刻退出主循环.
  3. 不同在于 : 如果event_base当前正在执行激活事件的回调, 调用event_base_loopexit是在执行完当前正在处理的事件后立即退出.

猜你喜欢

转载自blog.csdn.net/Function_Dou/article/details/87891384