下面开始看初始化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 (base);
}

我们发现event_init()工作量很少,只是调用event_base_new()函数,所以真正初始化event_base的工作是在event_base_new()函数内完成。

event_base_new()

struct event_base *
event_base_new(void) //初始化libevent的event_base
{
int i;
struct event_base *base;
if ((base = calloc(, sizeof(struct event_base))) == NULL) //在堆上分配内存存储event_base,所有字段初始化为0
event_err(, "%s: calloc", __func__);
event_sigcb = NULL;
event_gotsig = ;
detect_monotonic(); //设置use_monotonic变量
gettime(base, &base->event_tv); //base->tv_cache.tv_sec非0,则赋给base->event_tv min_heap_ctor(&base->timeheap); //初始化定时事件的小根堆base->timeheap min_heap.h
TAILQ_INIT(&base->eventqueue); //初始化注册事件链表base->eventqueue sys/queue.h
base->sig.ev_signal_pair[] = -; //初始化信号base->sig
base->sig.ev_signal_pair[] = -; base->evbase = NULL; //初始化I/O多路复用 base->evbase
//遍历全局数组eventops[],初始化libevent的I/O多路复用机制
for (i = ; eventops[i] && !base->evbase; i++) { //以NULL标志数组结尾,只选取一个I/O多路复用机制
base->evsel = eventops[i]; //初始化base->evsel
base->evbase = base->evsel->init(base); //初始化base->evbase
}
if (base->evbase == NULL) //没有I/O多路复用
event_errx(, "%s: no event mechanism available", __func__);
if (evutil_getenv("EVENT_SHOW_METHOD")) //调用getenv()获取环境变量EVENT_SHOW_METHOD evutil.c
event_msgx("libevent using: %s\n",
base->evsel->name);
/* allocate a single active event queue */
//event_base_new()内调用event_base_priority_init()
event_base_priority_init(base, ); //设置优先级base->nactivequeues;分配数组base->activequeues。数组大小和优先级相同
return (base);
}

其中由3点需要注意:

1.该函数调用calloc()在堆上分配内存来存储event_base;

2.使用全局数组eventops[]存储系统支持的I/O多路复用机制,然后遍历该数组,选取第1个I/O多路复用机制。

3.libevent支持event有优先级,所以又调用了event_base_priority_init()来完成优先级相关的设置。

event_base_priority_init()

//设置不同event的优先级,值越小,优先级越高
//返回值:0,成功;-1,出错
int
event_base_priority_init(struct event_base *base, int npriorities)
{
int i;
if (base->event_count_active) //当前base上有活跃的events则不能设置优先级,返回。
return (-);
if (npriorities == base->nactivequeues) //设置的优先级和当前优先级相同,则直接返回
return ();
if (base->nactivequeues) { //不同,则先释放原先的activequeues数组
for (i = ; 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, sizeof(struct event_list *)); //设置和优先级值相同大小的event_list数组
if (base->activequeues == NULL)
event_err(, "%s: calloc", __func__);
for (i = ; i < base->nactivequeues; ++i) {
base->activequeues[i] = malloc(sizeof(struct event_list)); //初始化activequeues数组中每个元素
if (base->activequeues[i] == NULL)
event_err(, "%s: malloc", __func__);
TAILQ_INIT(base->activequeues[i]);
}
return ();
}

该函数设置优先级,初始化了event_base的nactivequeues成员和activequeues成员。优先级值越小,优先级越高。在活跃事件链表中,优先级高的event先被处理。

Libevent源码分析—event_init()的更多相关文章

  1. 【转】libevent源码分析

    libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...

  2. Libevent源码分析 (1) hello-world

    Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...

  3. Libevent源码分析系列【转】

    转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了 ...

  4. Libevent源码分析系列

    1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒 ...

  5. libevent源码分析

    这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...

  6. Libevent源码分析—event_base_dispatch()

    我们知道libevent是一个Reactor模式的事件驱动的网络库.   到目前为止,我们已经看了核心的event和event_base结构体的源码,看了初始化这两个结构体的源码,看了注册event的 ...

  7. libevent源码分析二--timeout事件响应

    libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1.  min_heap ...

  8. libevent源码分析一--io事件响应

    这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select l ...

  9. Libevent源码分析—event, event_base

    event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...

随机推荐

  1. 重新认识JavaScript里的创建对象(一)

    一.序 面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.ECMA-262把对象定义为"无序属性的集合,其属性可以包含基本值.对象或者函数&quo ...

  2. 常用 SQL 语句使用的总结

    --SQL 语句为表添加字段并设置默认值 alter table Student --表名 add fee --添加的字段名 int --字段类型 not null --是否为空 --默认值 --修改 ...

  3. loopj.com android-async-http

    loopj.com android-async-http Android异步Http客户端 用于Android的基于回调的Http客户端库   下载版本1.4.9(最新) 或者在github上fork ...

  4. 关于ajax post请求,参数过大产生的问题解决 Java

    之前做了一个图片上传的功能,前端是把图片编码成BASE64,但是图片一大了,后台用request.getParameter("前端参数");来接收参数打印不出来,没有值,这就很尴尬 ...

  5. C#小知识点记录,对象的深拷贝

    在CSDN中的定义是: public static string CompareExchange( ref string location1, string value, string compara ...

  6. Android中调用文件管理器并返回选中文件的路径

    实际项目中经常需要调用文件管理器,选择下载路径或者上传的本地文件路径.今天就给大家做个demo示范该功能的实现过程. 一.实现效果预览 以下为三星S6的样机测试效果,当然不同手机调用后的效果不一样. ...

  7. SQL检索记录

    <<第一章检索记录>>:关于表使用SELECT语句和特殊字符"*": *:SELECT * from emp; 1:分别列出每一行:SELECT empno ...

  8. <JAVA>可变参数列表

    这是java1.5版本的新特性,就是当你想定义一个方法,但是不知道以后要用的时候传几个参数进去,这时可以在方法的参数列表中这样写(参数类型... 数组名),然后在方法内部直接用操作数组的方式操作.比如 ...

  9. hdu1711kmp

    Given two sequences of numbers : a11, a22, ...... , aNN, and b11, b22, ...... , bMM (1 <= M <= ...

  10. Codeforces Round #410 (Div. 2)D题

    D. Mike and distribution time limit per test 2 seconds memory limit per test 256 megabytes input sta ...