Пример #1
0
void
bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now,
    void *arg) {
	struct bufferevent *bufev = arg;
	if (bufev->wm_read.high == 0 || now < bufev->wm_read.high) {
		evbuffer_setcb(buf, NULL, NULL);

		if (bufev->enabled & EV_READ)
			bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	}
}
Пример #2
0
static void
bufferevent_readcb(int fd, short event, void *arg)
{
	struct bufferevent *bufev = arg;
	int res = 0;
	short what = OPAL_EVBUFFER_READ;
	size_t len;

	if (event == OPAL_EV_TIMEOUT) {
		what |= OPAL_EVBUFFER_TIMEOUT;
		goto error;
	}

	res = evbuffer_read(bufev->input, fd, -1);
	if (res == -1) {
		if (errno == EAGAIN || errno == EINTR)
			goto reschedule;
		/* error case */
		what |= OPAL_EVBUFFER_ERROR;
	} else if (res == 0) {
		/* eof case */
		what |= OPAL_EVBUFFER_EOF;
	}

	if (res <= 0)
		goto error;

	bufferevent_add(&bufev->ev_read, bufev->timeout_read);

	/* See if this callbacks meets the water marks */
	len = OPAL_EVBUFFER_LENGTH(bufev->input);
	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
		return;
	if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
		struct evbuffer *buf = bufev->input;
		opal_event_del(&bufev->ev_read);

		/* Now schedule a callback for us */
		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
		return;
	}

	/* Invoke the user callback - must always be called last */
	(*bufev->readcb)(bufev, bufev->cbarg);
	return;

 reschedule:
	bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	return;

 error:
	(*bufev->errorcb)(bufev, what, bufev->cbarg);
}
Пример #3
0
void
bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now,
    void *arg) {
	struct bufferevent *bufev = arg;
	/* 
	 * If we are below the watermark then reschedule reading if it's
	 * still enabled.
	 */
	if (bufev->wm_read.high == 0 || now < bufev->wm_read.high) {
		evbuffer_setcb(buf, NULL, NULL);

		if (bufev->enabled & EV_READ)
			bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	}
}
Пример #4
0
static void
buffertls_readcb(int fd, short event, void *arg)
{
	struct buffertls *buftls = arg;
	struct bufferevent *bufev = buftls->bt_bufev;
	struct tls *ctx = buftls->bt_ctx;
	int res = 0;
	short what = EVBUFFER_READ;
	size_t len;
	int howmuch = -1;

	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.
	 */
	if (bufev->wm_read.high != 0) {
		howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input);
		/* we might have lowered the watermark, stop reading */
		if (howmuch <= 0) {
			struct evbuffer *buf = bufev->input;
			event_del(&bufev->ev_read);
			evbuffer_setcb(buf,
			    bufferevent_read_pressure_cb, bufev);
			return;
		}
	}

	res = evtls_read(bufev->input, fd, howmuch, ctx);
	switch (res) {
	case TLS_WANT_POLLIN:
		bufferevent_add(&bufev->ev_read, bufev->timeout_read);
		return;
	case TLS_WANT_POLLOUT:
		event_del(&bufev->ev_write);
		event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_readcb,
		    buftls);
		bufferevent_add(&bufev->ev_write, bufev->timeout_write);
		return;
	case -1:
		what |= EVBUFFER_ERROR;
		break;
	case 0:
		what |= EVBUFFER_EOF;
		break;
	}
	if (res <= 0)
		goto error;

	event_del(&bufev->ev_write);
	event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
	if (bufev->enabled & EV_READ)
		bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & EV_WRITE)
		bufferevent_add(&bufev->ev_write, bufev->timeout_write);

	/* See if this callbacks meets the water marks */
	len = EVBUFFER_LENGTH(bufev->input);
	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
		return;
	if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) {
		struct evbuffer *buf = bufev->input;
		event_del(&bufev->ev_read);

		/* Now schedule a callback for us when the buffer changes */
		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
	}

	/* Invoke the user callback - must always be called last */
	if (bufev->readcb != NULL)
		(*bufev->readcb)(bufev, bufev->cbarg);
	return;

 error:
	(*bufev->errorcb)(bufev, what, bufev->cbarg);
}
Пример #5
0
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;

	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.
	 */
	if (bufev->wm_read.high != 0) {
		howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input);
		/* we might have lowered the watermark, stop reading */
		if (howmuch <= 0) {
			struct evbuffer *buf = bufev->input;
			event_del(&bufev->ev_read);
			evbuffer_setcb(buf,
			    bufferevent_read_pressure_cb, bufev);
			return;
		}
	}

	res = evbuffer_read(bufev->input, fd, howmuch);
	if (res == -1) {
		if (errno == EAGAIN || errno == EINTR)
			goto reschedule;
		/* error case */
		what |= EVBUFFER_ERROR;
	} else if (res == 0) {
		/* eof case */
		what |= EVBUFFER_EOF;
	}

	if (res <= 0)
		goto error;

	bufferevent_add(&bufev->ev_read, bufev->timeout_read);

	/* See if this callbacks meets the water marks */
	len = EVBUFFER_LENGTH(bufev->input);
	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
		return;
	if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) {
		struct evbuffer *buf = bufev->input;
		event_del(&bufev->ev_read);

		/* Now schedule a callback for us when the buffer changes */
		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
	}

	/* Invoke the user callback - must always be called last */
	if (bufev->readcb != NULL)
		(*bufev->readcb)(bufev, bufev->cbarg);
	return;

 reschedule:
	bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	return;

 error:
	(*bufev->errorcb)(bufev, what, bufev->cbarg);
}
Пример #6
0
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;

	if (event == EV_TIMEOUT) {
		what |= EVBUFFER_TIMEOUT;
		goto error;
	}

	if (bufev->wm_read.high != 0) {
		howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input);
		
		if (howmuch <= 0) {
			struct evbuffer *buf = bufev->input;
			event_del(&bufev->ev_read);
			evbuffer_setcb(buf,
			    bufferevent_read_pressure_cb, bufev);
			return;
		}
	}

	res = evbuffer_read(bufev->input, fd, howmuch);
	if (res == -1) {
		if (errno == EAGAIN || errno == EINTR)
			goto reschedule;
		
		what |= EVBUFFER_ERROR;
	} else if (res == 0) {
		
		what |= EVBUFFER_EOF;
	}

	if (res <= 0)
		goto error;

	bufferevent_add(&bufev->ev_read, bufev->timeout_read);

	
	len = EVBUFFER_LENGTH(bufev->input);
	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
		return;
	if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) {
		struct evbuffer *buf = bufev->input;
		event_del(&bufev->ev_read);

		
		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
	}

	
	if (bufev->readcb != NULL)
		(*bufev->readcb)(bufev, bufev->cbarg);
	return;

 reschedule:
	bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	return;

 error:
	(*bufev->errorcb)(bufev, what, bufev->cbarg);
}
Пример #7
0
/*
 * zark: 当epoll层的读事件到来, 会从活跃队列中回调该函数,
 *       开始从socket中读取数据.
 */
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;

    //! zark: bufferevent是对I/O操作的封装, 所以不监听超时事件.
	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.
     *
     * zark: 这里有必要普及一下libevent关于输入输出时的水位概念.
     *      读取低水位 - 读取操作使得输入缓冲区的数据量在此级别或者更高时,
     *                   读取回调将被调用.默认值为0, 所以每个读取操作都会
     *                   导致读取回调被调用.
     *      读取高水位 - 输入缓冲区中的数据量达到此级别后,bufferevent将停
     *                   止读取,直到输入缓冲区中足够量的数据被抽取,使得数
     *                   据量低于此级别.默认值是无限, 所以永远不会因为输入
     *                   缓冲区的大小而停止读取.
     *      写入低水位 - 写入操作使得输出缓冲区的数据量达到或者低于此级别时,
     *                   写入回调将被调用.默认值是0, 所以只有输出缓冲区空的
     *                   时候才会调用写入回调.
     *      写入高水位 - bufferevent没有直接使用这个水位. 它在bufferevent用
     *                   作另外一个bufferevent的底层传输端口时有特殊意义.请
     *                   看后面关于过滤型bufferevent的介绍.
	 */

    //! zark: 读取高水位到达, 停止读取.
	if (bufev->wm_read.high != 0) {
		howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input);
		/* we might have lowered the watermark, stop reading */
		if (howmuch <= 0) {
			struct evbuffer *buf = bufev->input;
			event_del(&bufev->ev_read); //! 删除当前读事件.
            /*
             * zark: 设置一个新的读事件, 该读事件的callback函
             *       数(即bufferevent_read_pressure_cb)会检测
             *       当输入冲区大小小于高水位时, 会再次添加正
             *       常的读取event.
             */
			evbuffer_setcb(buf,
			    bufferevent_read_pressure_cb, bufev);
			return;
		}
	}

    /*
     * zark: 开始从fd读取数据到我们的输入缓冲区中.
     */
	res = evbuffer_read(bufev->input, fd, howmuch);
	if (res == -1) {
		if (errno == EAGAIN || errno == EINTR)
			goto reschedule;
		/* error case */
		what |= EVBUFFER_ERROR;
	} else if (res == 0) {
		/* eof case */
		what |= EVBUFFER_EOF;
	}

	if (res <= 0)
		goto error;

    /*
     * zark: 因为bufferevent当初添加事件的时候没有使用
     *       persist来修饰event, 所以需要重新添加.
     */
	bufferevent_add(&bufev->ev_read, bufev->timeout_read);

	/* See if this callbacks meets the water marks */
	len = EVBUFFER_LENGTH(bufev->input);

    /*
     * zark: 读取低水位线没有达到, 所以不能调用callback, 直接return~
     */
	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
		return;

    /*
     * zark: 读取高水位到达, 停止读取.
     */
	if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) {
		struct evbuffer *buf = bufev->input;
		event_del(&bufev->ev_read);

		/* Now schedule a callback for us when the buffer changes */
		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
	}

	/* Invoke the user callback - must always be called last */
    /*
     * zark: 哈哈, 一顿乱七八糟的check下来, 终于到了调用我们
     *       真正注册的读取回调函数拉~ 散花~
     */
	if (bufev->readcb != NULL)
		(*bufev->readcb)(bufev, bufev->cbarg);
	return;

 reschedule:
	bufferevent_add(&bufev->ev_read, bufev->timeout_read);
	return;

    /*
     * zark: 调用我们注册的错误处理回调函数.
     */
 error:
	(*bufev->errorcb)(bufev, what, bufev->cbarg);
}