前言
在上一节中,我们介绍了bufferevent实现自动管理的基本思想(水位线机制),在本小节中,我们将介绍bufferevent_readcb
、bufferevent_writecb
等函数,了解它工作的全过程。
bufferevent_readcb
static void
bufferevent_readcb(int fd, short event, void *arg)
{
struct bufferevent *bufev = arg;
int res = 0;
short what = EVBUFFER_READ;
size_t len;
int howmuch = -1;
/* Note that we only check for event==EV_TIMEOUT. If
* event==EV_TIMEOUT|EV_READ, we can safely ignore the
* timeout, since a read has occurred */
/* 这个回调函数只有当缓冲区可读时才应被触发
* 如果是因为超时被触发,则直接跳转到error处
*/
if (event == EV_TIMEOUT) {
what |= EVBUFFER_TIMEOUT;
goto error;
}
/*
* If we have a high watermark configured then we don't want to
* read more data than would make us reach the watermark.
*/ //先检测input缓冲区已有的数据
/* 不为0代表高水位被设置了(默认高水位是0(代表无限))
* 既然高水位被设置了,那么就需要检测是否超过水位了
*/
if (bufev->wm_read.high != 0) { //如果读取高水位不为0
howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input); //到达高水位剩余的值
/* we might have lowered the watermark, stop reading */
//小于0,则代表越水位了,bufferevent停止读取
if (howmuch <= 0) {
struct evbuffer *buf = bufev->input;
//将可读事件删掉
event_del(&bufev->ev_read);
evbuffer_setcb(buf,
bufferevent_read_pressure_cb, bufev);
return; //直接返回
}
}
//从fd读取数据到输入缓冲区
res = evbuffer_read(bufev