前言
在上节中,我们将evbuffers剩余的内容,比如读/写操作进行了剖析。接下来,我们将对bufferevent进行分析,它主要实现了对缓冲区的自动管理。
在本节中,我们先介绍相关结构体以及一些管理操作,相关代码在evbuffer.c
以及event.h
文件中。
struct bufferevent
该结构体用于管理bufferevent。定义如下:
struct bufferevent {
struct event_base *ev_base; //与缓冲区相关联的event_base
struct event ev_read; //缓冲区读事件
struct event ev_write; //缓冲区写事件
struct evbuffer *input; //输入缓冲区
struct evbuffer *output; //输出缓冲区
struct event_watermark wm_read; //读水位
struct event_watermark wm_write; //写水位
evbuffercb readcb; //缓冲区读回调函数
evbuffercb writecb; //缓冲区写回调函数
everrorcb errorcb; //发生错误的回调函数
void *cbarg; //回调函数的参数
int timeout_read; /* in seconds */
int timeout_write; /* in seconds */
short enabled; //当前启用的事件/* events that are currently enabled */
};
里面又有一个陌生的结构体,struct event_watermark
,它也在event.h
中定义:
struct event_watermark {
size_t low; //低水位
size_t high; //高水位
}
它之所以可以自动管理缓冲区就是因为水位以及相应回调函数的设置。一共有4个水位,分别是读取低水位、读取高水位、写入低水位、写入高水位,它们的作用分别如下:
- 读取低水位:当读取操作使输入缓冲区的数据大小超过或等于该水位时,就会调用回调函数。而读取低水位的默认值是0,所以每一次进行读取操作都会导致回调函数被调用。
- 读取高水位:它相当于一个警戒线,当输入缓冲区的数据量达到该水位,则停止数据的读取,直到水位回退。它的默认值是无限。
- 写入低水位:写入操作使得输出缓冲区的数据量低于或等于该水位时,会调用相关的回调函数。默认值是0,所以只有当输出缓冲区为空时才会调用回调函数。
- 写入高水位:bufferevent没有直接使用这个水位。它在bufferevent用作另外一个bufferevent的底层传输端口时有特殊意义。
接下来了解这些基本信息,我们先来看看初始化操作。
新建一个bufferevent
struct bufferevent *
bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb,
everrorcb errorcb, void *cbarg)
{
struct bufferevent *bufev;
//申