[libevent源码分析] event_init

libevent采用的是经典的reactor网络框架,集成了信号、定时、网络事件于一体

首先对event_init进行源码剖析

event_init 主要创建event_base对象,

struct event_base {
	const struct eventop *evsel;      //lievent支持select epoll kequeue..等网络api,包括init、add、del、dispatch的接口,每种网络框架都支持
	void *evbase;                     //支持相应网络api的 结构对象,必须epoll就是epoll_create返回epfd相关的内容,
    //因为每种网络接口都不一样,所以需要使用void*
	int event_count;		          //总网络事件数
	int event_count_active;	          //激活事件数

	int event_gotterm;		         //event_base_dispatch中终止while循环
	int event_break;		         //event_base_dispatch终止while立刻

	struct event_list **activequeues;//用于保存激活事件列表,是一个二维数组,第一维用于权限number,越低越高,第二维为激活列表
	int nactivequeues;              // 激活权限列表有多少个权限

	struct evsignal_info sig;       //保存着信号相关的内容

	struct event_list eventqueue;   //保存着注册的事件列表
	struct timeval event_tv;        //用于和tv_cache确定是否时间被修改了,如果使用monotonic时间是不被修改的,gettimeofday才会用到

	struct min_heap timeheap;       //用于时间堆(最小堆)管理

	struct timeval tv_cache;
};

代码如下

struct event_base *
event_init(void)
{
	struct event_base *base = event_base_new();

	if (base != NULL)
		current_base = base;//如果创建成功那么就会把current_base更新为新创建的base

	return (base);
}

event_init 此函数用于对外提供接口,主要完成的初始化event_base对象,同时如果cc创建成功那么就把current_base指向新创建的event_base,用于默认event_base

下面是创建和初始化event_base整个函数

struct event_base *
event_base_new(void)
{
	int i;
	struct event_base *base;

    //先创建一个even_base对象
	if ((base = calloc(1, sizeof(struct event_base))) == NULL)
		event_err(1, "%s: calloc", __func__);

	event_sigcb = NULL;
	event_gotsig = 0;

    //检测系统是否可以使用MONOTONIC time
	detect_monotonic();
    //填充base->event_tv记录创建base的时间
	gettime(base, &base->event_tv);

    //初始化最小定时器堆,p n a都置为0
	min_heap_ctor(&base->timeheap);
    //初始化队列first = NULL and last = &first
	TAILQ_INIT(&base->eventqueue);
    //初始化用于信号通信的socket,使用的是sockpair unix网络套接字
	base->sig.ev_signal_pair[0] = -1;
	base->sig.ev_signal_pair[1] = -1;

	base->evbase = NULL;
	for (i = 0; eventops[i] && !base->evbase; i++) {
    //event会优先选择epoll,这个数组是按照索引优先权下降
		base->evsel = eventops[i];

		base->evbase = base->evsel->init(base);
	}

	if (base->evbase == NULL)
		event_errx(1, "%s: no event mechanism available", __func__);

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

	/* allocate a single active event queue */
	event_base_priority_init(base, 1);

	return (base);
}

detect_monotonic用于检测当前使用的时间更新机制,查看是否可以调用clock_m_geeettime函数来设置use_monotonic

getttime用于初始化event_tv

min_head_ctor初始化最小堆数组结构,a n p

TAIL_INIT(&base->event_tv)用于初始化注册事件双向链表

整个for循环是为了选取最优的网络接口模型,同时初始化这个网络模型数据结构

下面是初始化激活网络事件权限

int
event_base_priority_init(struct event_base *base, int npriorities)
{
	int i;

	if (base->event_count_active)
		return (-1);
    //先释放
	if (base->nactivequeues && npriorities != base->nactivequeues) {
		for (i = 0; i < base->nactivequeues; ++i) {
			free(base->activequeues[i]);
		}
		free(base->activequeues);
	}

	/* Allocate our priority queues */
    //先分配一维权限数组
	base->nactivequeues = npriorities;
	base->activequeues = (struct event_list **)calloc(base->nactivequeues,
	    npriorities * sizeof(struct event_list *));
	if (base->activequeues == NULL)
		event_err(1, "%s: calloc", __func__);

    //再初始化二维激活事件列表
	for (i = 0; i < base->nactivequeues; ++i) {
		base->activequeues[i] = malloc(sizeof(struct event_list));
		if (base->activequeues[i] == NULL)
			event_err(1, "%s: malloc", __func__);
		TAILQ_INIT(base->activequeues[i]);
	}

	return (0);
}

libeven 整个源码分析和sample都在我的 githup

时间: 2024-10-17 14:14:38

[libevent源码分析] event_init的相关文章

Libevent源码分析—event_init()

下面开始看初始化event_base结构的相关函数.相关源码位于event.c event_init() 首先调用event_init()初始化event_base结构体 struct event_base * event_init(void) { struct event_base *base = event_base_new(); //event_init()调用event_base_new() if (base != NULL) current_base = base; return (b

【转】libevent源码分析

libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库.Libevent有几个显著的亮点: (1)事件驱动(event-driven),高性能:(2)轻量级,专注于网络,不如 ACE 那么臃肿庞

Libevent源码分析-timer和signal处理

timer处理 Signal处理 timerfd和signalfd timerfd signalfd timer处理 在Libevent源码分析-event处理流程中,使用了定时器,来看一下源码: evtimer_set(&ev, time_cb, NULL);//设置定时器事件 其中evtimer_set是个宏定义 #define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) //event_set原型 void ev

Libevent源码分析 (1) hello-world

Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libevent的源码,凡是我觉得有必要的内容均一一记录,与君共勉. 首先要说说什么是libevent: libevent是一个事件通知库,libevent API提供一种机制使得我们可以在一个文件描述符(file descriptor)发生特定事件时或者timeout发生时执行指定的回调函数.libevent意

Libevent源码分析系列【转】

转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒输出一行信息. test.c 2.event, event_base 经过第1步,下面开始看上面程序中的每一部分的源码.首先是两个核心结构体event和event_base event event_base源码

libevent源码分析-event

event结构 event相关接口 Libevent对event的管理 event结构 event是Reactor模式中的最重要的组件.它包含了了一个句柄fd,并设置监听这个句柄上的哪些事件(读/写等),设置了对应的函数指针,在事件到来时,回调函数指针来处理事件. 先看一下event的结构.它位于include/event2/event_struct.h中 struct event { TAILQ_ENTRY(event) ev_active_next; TAILQ_ENTRY(event) e

[libevent源码分析] event_set

libevent使用event来封装网络事件回调,参数.fd...等一些信息,函数很简单 void event_set(struct event *ev, int fd, short events, void (*callback)(int, short, void *), void *arg) { /* Take the current base - caller needs to set the real base later */ ev->ev_base = current_base; /

[libevent源码分析] event_add

event_add 把event往当前event中的ev_base追加,如果需要定时,那么tv不能为空 int event_add(struct event *ev, const struct timeval *tv) { struct event_base *base = ev->ev_base; //event_add 会把event加入到他的ev_base成员里 const struct eventop *evsel = base->evsel; //对应linux的epoll相关函数

[libevent源码分析] event_base_dispatch

分析下事件循环 event_base_dispatch int event_base_dispatch(struct event_base *event_base) { return (event_base_loop(event_base, 0)); } int event_base_loop(struct event_base *base, int flags) { const struct eventop *evsel = base->evsel; void *evbase = base->