libevent0.1&0.2源码理解(一)类型与变量

修改记录:
3-28 初稿
3-39 补充了全局变量说明,补充了0.2的内容

libevent是一个高性能的异步处理函数库。使用libevent库的著名软件有chromium、memcached、Tor等等。
网上libevent的中文文档不是很少,其中[url=http://blog.csdn.net/sparkliang/article/category/660506]张亮写的libevent源码分析[/url]写得不错。但是当时的1.4版本篇幅还是过长,本文将浅析libevent的0.1及0.2版本,其中体现了libevent最基础的东西,希望能给诸位一个快速的印象。
还是请注意,现在的libevent2与之前的版本很不一样了。

[b]基本类型[/b]
libevent最基础的数据类型是event
struct event {
TAILQ_ENTRY (event) ev_read_next;
TAILQ_ENTRY (event) ev_write_next;
TAILQ_ENTRY (event) ev_timeout_next;
TAILQ_ENTRY (event) ev_add_next;

int ev_fd; //包含的socket套接字,是event的核心
short ev_events; //对应的事件集

struct timeval ev_timeout; //定时器

void (*ev_callback)(int, short, void *arg); //对应的回调函数
void *ev_arg; //参数

int ev_flags; //标志
};

这里最难理解的就是TAILQ_ENTRY了,这个宏是定义在queue.h文件当中
#define TAILQ_ENTRY(type)						\
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}

从宏定义可以看出,此结构体没有名字,所以只能在某一个结构体中被使用(这里就是struct event)
这里定义的是一个tail queue的结构,该结构比较好玩,本人之前把它误想成双向链表了,但仔细看看,似乎还不全是。
tqe_next很常见,指向下一个元素
tqe_prev是 前面一个元素当中 指向下一个元素的 那个指针的指针……所以有2个星号。(在写本文之时,我还不清楚为什么要这么绕)

回过头来看,
ev_read_next可以用来找到在队列中下一个可以准备读的套接字
ev_write_next可以用来找到在队列中下一个可以准备写的套接字
ev_timeout_next可以用来找到在队列中下一个定时器
ev_add_next可以用来找到在队列中下一个需要处理的事件

0.2版本中增加了提供多平台网络编程的包装结构
struct eventop {
char *name;
void *(*init)(void);
int (*add)(void *, struct event *); //事件增加的回调函数,下同,全字面意思不解释
int (*del)(void *, struct event *);
int (*recalc)(void *, int);
int (*dispatch)(void *, struct timeval *);
};



[b]全局变量[/b]
刚才说到队列,可是在使用库的时候,哪来得队列呢?
这是在event.c文件中已经定义的全局变量
TAILQ_HEAD (timeout_list, event) timequeue; //定时器队列的头结点
TAILQ_HEAD (event_wlist, event) writequeue; //写队列的头结点
TAILQ_HEAD (event_rlist, event) readqueue; //读队列的头结点
TAILQ_HEAD (event_ilist, event) addqueue; //待处理队列的头结点
其中timequeue这个定时器队列是按照结构体timeval从小到大的顺序进行排列的,后面增加事件时会提到。

int event_inloop = 0; //锁。用于判断程序此时是否在轮询之中
int event_fds; /* Highest fd in fd set */
int event_fdsz; //size。用于计算event_fds总共要用多大空间
fd_set *event_readset; //对应于select的readset
fd_set *event_writeset; //对应于select的writeset


0.2版本中增加的全局变量
struct eventop *evsel;
void *evbase;

event.c当中存在一个全局数组struct eventop *eventops[]用于指示系统当中有以下哪些网络处理函数可使用:kqueue, epoll, poll, select等等。
然后程序会选择一个传给evsel
evsel会调用初始化函数返回一个指向网络处理函数结构体的指针给evbase。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值