Libevent源码剖析(三)

事件集合(struct event_base)

struct event_base *event_base_new(void)

其中有很多的函数已经追踪阅读,但是没有展示,设计思想不难,但是代码由于#define的存在,有点复杂。

Order 0:struct event_base *event_base_new(void)

struct event_base * event_base_new(void)
{
        struct event_base *base = NULL;
	struct event_config *cfg = event_config_new();        //获取一个struct event_config对象
	if (cfg) {        //如果对象获取成功,根据config对struct event_base对象进行设置,然后free config object
		base = event_base_new_with_config(cfg);
		event_config_free(cfg);
	}
	return base;
}

Order 1:struct event_config* event_config_new(void)void event_config_free(struct event_config *cfg)

struct event_config* event_config_new(void)
{
	struct event_config *cfg = mm_calloc(1, sizeof(*cfg));        //从自定义的alloc中分配一块空间用于存放config object

	if (cfg == NULL)        //如果分配失败,返回NULL
		return (NULL);

	TAILQ_INIT(&cfg->entries);        //初始化config object的双向队列
	cfg->max_dispatch_interval.tv_sec = -1;        //如果为-1,则在没有事件时陷入等待,直到有事件发生。
	cfg->max_dispatch_callbacks = INT_MAX;        //将callback的处理限制为INT_MAX
	cfg->limit_callbacks_after_prio = 1;        //优先级默认为1,就是全局只有这么一个优先级

	return (cfg);
}

void event_config_free(struct event_config *cfg)
{
	struct event_config_entry *entry;        //从config object中逐个取出struct event_config_entry对象(这个对象中没啥实际的东西)并删除

	while ((entry = TAILQ_FIRST(&cfg->entries)) != NULL) {
		TAILQ_REMOVE(&cfg->entries, entry, next);
		event_config_entry_free(entry);
	}
	mm_free(cfg);        //归还config Object内存
}

Order 1:struct event_base * event_base_new_with_config(const struct event_config *cfg)

struct event_base * event_base_new_with_config(const struct event_config *cfg)
{
	int i;
	struct event_base *base;
	int should_check_environment;

#ifndef EVENT__DISABLE_DEBUG_MODE
	event_debug_mode_too_late = 1;
#endif

	if ((base = mm_calloc(1, sizeof(struct event_base))) == NULL) {        //获取存储struct event_base的对象
		event_warn("%s: calloc", __func__);
		return NULL;
	}

	if (cfg)    //根据config对象设置event_base
		base->flags = cfg->flags;

	should_check_environment =
	    !(cfg && (cfg->flags & EVENT_BASE_FLAG_IGNORE_ENV));        //判断是否需要检查当前环境

	{
		struct timeval tmp;
		int precise_time =
		    cfg && (cfg->flags & EVENT_BASE_FLAG_PRECISE_TIMER);        //检查是否设置了精确时间的选项
		int flags;
		if (should_check_environment && !precise_time) {
			precise_time = evutil_getenv_("EVENT_PRECISE_TIMER") != NULL;
			base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER;
		}
		flags = precise_time ? EV_MONOT_PRECISE : 0;        //判断是否需要精确时间选项
		evutil_configure_monotonic_time_(&base->monotonic_timer, flags);        //配置那个为空的对象

		gettime(base, &tmp);        //获取时间
	}

	min_heap_ctor_(&base->timeheap);        //将超时时间以最小堆组织起来

	base->sig.ev_signal_pair[0] = -1;        //将sockpair处理的事件机制的fd初始化为-1
	base->sig.ev_signal_pair[1] = -1;
	base->th_notify_fd[0] = -1;
	base->th_notify_fd[1] = -1;

	TAILQ_INIT(&base->active_later_queue);        //初始化下一轮循环通知的事件初始化

	evmap_io_initmap_(&base->io);        //初始化IO事件map(HASH)
	evmap_signal_initmap_(&base->sigmap);        //初始化信号事件(HASH)
	event_changelist_init_(&base->changelist);        //初始化事件修改链表

	base->evbase = NULL;        //将指向特定数据的指针初始化为NULL

	if (cfg) {
		memcpy(&base->max_dispatch_time,
		    &cfg->max_dispatch_interval, sizeof(struct timeval));        //根据config对象,初始化struct event_base的:
		base->limit_callbacks_after_prio =
		    cfg->limit_callbacks_after_prio;
	} else {
		base->max_dispatch_time.tv_sec = -1;        //事件循环时间
		base->limit_callbacks_after_prio = 1;        //事件优先级
	}
	if (cfg && cfg->max_dispatch_callbacks >= 0) {        //初始化事件处理的最大数量
		base->max_dispatch_callbacks = cfg->max_dispatch_callbacks;
	} else {
		base->max_dispatch_callbacks = INT_MAX;
	}
	if (base->max_dispatch_callbacks == INT_MAX &&
	    base->max_dispatch_time.tv_sec == -1)
		base->limit_callbacks_after_prio = INT_MAX;        //初始化优先级数量

	for (i = 0; eventops[i] && !base->evbase; i++) {        //eventops是一个全局数据结构,如果全局数据结构存在并且base的私有数据不存在,就执行代码
		if (cfg != NULL) {        //如果有config object
			if (event_config_is_avoided_method(cfg,
				eventops[i]->name))        //将eventop中的name字符串,传递给配置对象
				continue;
			if ((eventops[i]->features & cfg->require_features)
			    != cfg->require_features)
				continue;
		}

		/* also obey the environment variables */
		if (should_check_environment &&
		    event_is_method_disabled(eventops[i]->name))
			continue;

		base->evsel = eventops[i];        //将信号处理ops注册给base的信号处理ops

		base->evbase = base->evsel->init(base);        //私有数据 = struct event_base对象??有可能是反向获取struct event_base的方式之一
	}

	if (base->evbase == NULL) {        //如果反向获取指针处理失败,直接返回
		event_warnx("%s: no event mechanism available",
		    __func__);
		base->evsel = NULL;
		event_base_free(base);
		return NULL;
	}

	if (evutil_getenv_("EVENT_SHOW_METHOD"))        
		event_msgx("libevent using: %s", base->evsel->name);

	/* allocate a single active event queue */
	if (event_base_priority_init(base, 1) < 0) {        //初始化事件处理的优先级队列
		event_base_free(base);
		return NULL;
	}

	/* prepare for threading */

#if !defined(EVENT__DISABLE_THREAD_SUPPORT) && !defined(EVENT__DISABLE_DEBUG_MODE)
	event_debug_created_threadable_ctx_ = 1;
#endif

	if (EVTHREAD_LOCKING_ENABLED() &&
	    (!cfg || !(cfg->flags & EVENT_BASE_FLAG_NOLOCK))) {
		int r;
		EVTHREAD_ALLOC_LOCK(base->th_base_lock, 0);        //初始化互斥锁
		EVTHREAD_ALLOC_COND(base->current_event_cond);        //初始化条件变量
		r = evthread_make_base_notifiable(base);        //这个函数会初始化与唤醒主线程的sockpair以及注册唤醒主线程的函数,都不难,可以很快用C++实现
		if (r<0) {
			event_warnx("%s: Unable to make base notifiable.", __func__);
			event_base_free(base);
			return NULL;
		}
	}

	return (base);        //返回已经初始化的struct event_base对象
}

void event_base_free(struct event_base *base)

Order 0:void event_base_free(struct event_base *base)

void event_base_free(struct event_base *base)
{
	event_base_free_(base, 1);
}

Order 1:static void event_base_free_(struct event_base *base, int run_finalizers)

static void event_base_free_(struct event_base *base, int run_finalizers)
{
	int i, n_deleted=0;
	struct event *ev;
	
	if (base == NULL && current_base)        //获取现有的struct event_base对象
		base = current_base;

	if (base == NULL) {
		event_warnx("%s: no base to free", __func__);
		return;
	}

	if (base->th_notify_fd[0] != -1) {        //在事件库中存在多个线程,终止时需要合理的处理这些线程
		event_del(&base->th_notify);        //从事件队列中删除与多线程通信的事件
		EVUTIL_CLOSESOCKET(base->th_notify_fd[0]);        //关闭管道fd
		if (base->th_notify_fd[1] != -1)
			EVUTIL_CLOSESOCKET(base->th_notify_fd[1]);        //关闭管道fd
		base->th_notify_fd[0] = -1;
		base->th_notify_fd[1] = -1;
		event_debug_unassign(&base->th_notify);        //测试这个event是否已经取消注册
	}

	evmap_delete_all_(base);        //删除事件链表中所有的IO事件与信号事件

	while ((ev = min_heap_top_(&base->timeheap)) != NULL) {        //从最小堆中删除所有的超时事件 
		event_del(ev);
		++n_deleted;
	}
	for (i = 0; i < base->n_common_timeouts; ++i) {        //这个管理超时事件的common没有搞懂
		struct common_timeout_list *ctl =
		    base->common_timeout_queues[i];
		event_del(&ctl->timeout_event); /* Internal; doesn't count */
		event_debug_unassign(&ctl->timeout_event);
		for (ev = TAILQ_FIRST(&ctl->events); ev; ) {
			struct event *next = TAILQ_NEXT(ev,
			    ev_timeout_pos.ev_next_with_common_timeout);
			if (!(ev->ev_flags & EVLIST_INTERNAL)) {
				event_del(ev);
				++n_deleted;
			}
			ev = next;
		}
		mm_free(ctl);
	}
	if (base->common_timeout_queues)        //释放公共超时事件队列
		mm_free(base->common_timeout_queues);

	for (;;) {        //回收处理事件的线程资源
		int i = event_base_free_queues_(base, run_finalizers);
		if (!i) {
			break;
		}
		n_deleted += i;
	}

	if (n_deleted)
		event_debug(("%s: %d events were still set in base",
			__func__, n_deleted));

	while (LIST_FIRST(&base->once_events)) {        //从只注册一次的事件,但是事件还没有发生的链表中,逐个删除事件
		struct event_once *eonce = LIST_FIRST(&base->once_events);
		LIST_REMOVE(eonce, next_once);
		mm_free(eonce);
	}

	if (base->evsel != NULL && base->evsel->dealloc != NULL)
		base->evsel->dealloc(base);        //使用注册的函数清理base

	for (i = 0; i < base->nactivequeues; ++i)        //在销毁struct event_base对象之前,逐个清理
		EVUTIL_ASSERT(TAILQ_EMPTY(&base->activequeues[i]));

	EVUTIL_ASSERT(min_heap_empty_(&base->timeheap));        //在销毁之前,确保最小堆已经被清理干净
	min_heap_dtor_(&base->timeheap);        //销毁最小堆

	mm_free(base->activequeues);        //释放活动事件队列

	evmap_io_clear_(&base->io);        //清理IO事件队列
	evmap_signal_clear_(&base->sigmap);        //清理信号事件队列
	event_changelist_freemem_(&base->changelist);        //清理改变事件队列

	EVTHREAD_FREE_LOCK(base->th_base_lock, 0);        //释放锁与条件变量
	EVTHREAD_FREE_COND(base->current_event_cond);

	if (base == current_base)
		current_base = NULL;
	mm_free(base);
}

int event_reinit(struct event_base *base)

Order 0:int event_reinit(struct event_base *base)

int event_reinit(struct event_base *base)
{
	const struct eventop *evsel;
	int res = 0;
	int was_notifiable = 0;
	int had_signal_added = 0;

	EVBASE_ACQUIRE_LOCK(base, th_base_lock);        //获取锁

	evsel = base->evsel;        //获取处理事件的ops

	if (evsel->need_reinit) {        //如果struct event_base对象在fork之后需要重新进行处理
		base->evsel = &nil_eventop;        //获取信号处理
	}

	if (base->sig.ev_signal_added) {
		event_del_nolock_(&base->sig.ev_signal, EVENT_DEL_AUTOBLOCK);
		event_debug_unassign(&base->sig.ev_signal);
		memset(&base->sig.ev_signal, 0, sizeof(base->sig.ev_signal));
		had_signal_added = 1;
		base->sig.ev_signal_added = 0;
	}
	if (base->sig.ev_signal_pair[0] != -1)
		EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
	if (base->sig.ev_signal_pair[1] != -1)
		EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
	if (base->th_notify_fn != NULL) {
		was_notifiable = 1;
		base->th_notify_fn = NULL;
	}
	if (base->th_notify_fd[0] != -1) {
		event_del_nolock_(&base->th_notify, EVENT_DEL_AUTOBLOCK);
		EVUTIL_CLOSESOCKET(base->th_notify_fd[0]);
		if (base->th_notify_fd[1] != -1)
			EVUTIL_CLOSESOCKET(base->th_notify_fd[1]);
		base->th_notify_fd[0] = -1;
		base->th_notify_fd[1] = -1;
		event_debug_unassign(&base->th_notify);
	}

	/* Replace the original evsel. */
        base->evsel = evsel;

	if (evsel->need_reinit) {
		/* Reconstruct the backend through brute-force, so that we do
		 * not share any structures with the parent process. For some
		 * backends, this is necessary: epoll and kqueue, for
		 * instance, have events associated with a kernel
		 * structure. If didn't reinitialize, we'd share that
		 * structure with the parent process, and any changes made by
		 * the parent would affect our backend's behavior (and vice
		 * versa).
		 */
		if (base->evsel->dealloc != NULL)
			base->evsel->dealloc(base);
		base->evbase = evsel->init(base);
		if (base->evbase == NULL) {
			event_errx(1,
			   "%s: could not reinitialize event mechanism",
			   __func__);
			res = -1;
			goto done;
		}

		/* Empty out the changelist (if any): we are starting from a
		 * blank slate. */
		event_changelist_freemem_(&base->changelist);

		/* Tell the event maps to re-inform the backend about all
		 * pending events. This will make the signal notification
		 * event get re-created if necessary. */
		if (evmap_reinit_(base) < 0)
			res = -1;
	} else {
		res = evsig_init_(base);
		if (res == 0 && had_signal_added) {
			res = event_add_nolock_(&base->sig.ev_signal, NULL, 0);
			if (res == 0)
				base->sig.ev_signal_added = 1;
		}
	}

	/* If we were notifiable before, and nothing just exploded, become
	 * notifiable again. */
	if (was_notifiable && res == 0)
		res = evthread_make_base_notifiable_nolock_(base);

done:
	EVBASE_RELEASE_LOCK(base, th_base_lock);
	return (res);
}
原文地址:https://www.cnblogs.com/ukernel/p/9191078.html