struct bufferevent定义在文件bufferevent_struct.h中。

 /**
Shared implementation of a bufferevent. This type is exposed only because it was exposed in previous versions,
and some people's code may rely on manipulating it. Otherwise, you
should really not rely on the layout, size, or contents of this structure:
it is fairly volatile, and WILL change in future versions of the code.
**/
struct bufferevent {
/** Event base for which this bufferevent was created. */
struct event_base *ev_base;
/** Pointer to a table of function pointers to set up how this
bufferevent behaves. */
const struct bufferevent_ops *be_ops; /** A read event that triggers when a timeout has happened or a socket
is ready to read data. Only used by some subtypes of
bufferevent. */
struct event ev_read;
/** A write event that triggers when a timeout has happened or a socket
is ready to write data. Only used by some subtypes of
bufferevent. */
struct event ev_write; /** An input buffer. Only the bufferevent is allowed to add data to
this buffer, though the user is allowed to drain it. */
struct evbuffer *input; /** An input buffer. Only the bufferevent is allowed to drain data
from this buffer, though the user is allowed to add it. */
struct evbuffer *output; struct event_watermark wm_read;
struct event_watermark wm_write; bufferevent_data_cb readcb;
bufferevent_data_cb writecb;
/* This should be called 'eventcb', but renaming it would break
* backward compatibility */
bufferevent_event_cb errorcb;
void *cbarg; struct timeval timeout_read;
struct timeval timeout_write; /** Events that are currently enabled: currently EV_READ and EV_WRITE
are supported. */
short enabled;
};

libevent中的event结构对应套接字的某一个事件,读或者写,bufferevent结构对应一个套接字,其中有两个event结构:evread、evwrite。

对bufferevent的操作主要有:

1、bufferevent_socket_new,分配一个bufferevent对象并初始化,该函数内部依次调用了bufferevent_init_common_、event_assign(evread)、event_assign(evwrite),在该函数中只是初始化了读写事件,并没有调用event_add,两个事件的回调函数分别是定义在bufferevent_socket.c中的bufferevent_readcb、bufferevent_writecb,传递的参数是bufferevent指针。

2、bufferevent_new,分配一个bufferevent对象并设置回调,该函数的实现其实是依次调用了bufferevent_socket_new和bufferevent_setcb。

3、bufferevent_setcb,为bufferevent结构设置readcb、writecb、eventcb。

4、bufferevent_init_common_,初始化bufferevent公共的部分成员,例如:be_ops(设置bufferevent的行为)。

5、bufferevent_enable,使bufferevent生效(前面说过,初始化的时候并未调用event_add),该函数调用bufferevent的成员be_ops.enable,根据上面bufferevent_init_common_函数可知,enable实际调用了bufferevent_ops_socket.be_socket_enable,be_socket_enable调用了bufferevent_add_event_函数,bufferevent_add_event_函数调用了event_add。所以由此可以得知,使得evread、evwrite事件有效的函数是bufferevent_enable。

6、bufferevent_disable,使bufferevent失效,该函数调用关系类似于bufferevent_enable,bufferevent_disable->bufferevent.be_ops->bufferevent_ops_socket.be_socket_disable->event_del。

按照我对libevent的理解,evwrite在写完数据应该是被设置为无效的,因为正常情况下,一个套接字一直是可写的,所以写事件一直是有效的,所以需要找到bufferevent是怎么管理evread、evwrite事件的。

bufferevent的作用就是对数据的读写做一个缓存,所以调用bufferevent_setcb函数传入的readcb、writecb、eventcb三个回调函数,其中readcb应该是读取了一些数据之后被回调的,此时数据已经被读取到了evbuffer中;而writecb应该是写入了一些数据之后被回调的,此时应该应该已经将evwrite设置为无效的了,应该在调用完send之后执行的。bufferevent封装了底层的recv和send。

在调用bufferevent_socket_new中,调用了evbuffer_add_cb函数为output(对应输出的evbuffer)设置了相应的回调函数bufferevent_socket_outbuf_cb,在该函数中调用了bufferevent_add_event_,从上面的分析可以知道该函数会使evwrite事件生效,也就是开始监听可读事件,所以这里是使evwrite生效的地方。

在bufferevent_writecb中,可以找到当output中没有数据时,确实调用了bufferevent_disable,所以这里就是使evwrite失效的地方,由此跟我上面的推测一样。

到这里,关于bufferevent的分析就结束了。

libevent源码分析:bufferevent的更多相关文章

  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源码分析二--timeout事件响应

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

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

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

  8. Libevent源码分析—event_init()

    下面开始看初始化event_base结构的相关函数.相关源码位于event.c event_init() 首先调用event_init()初始化event_base结构体 struct event_b ...

  9. Libevent源码分析—event, event_base

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

  10. Libevent源码分析—event_add()

    接下来就是将已经初始化的event注册到libevent的事件链表上,通过event_add()来实现,源码位于event.c中. event_add() 这个函数主要完成了下面几件事: 1.将eve ...

随机推荐

  1. BizTalk 2013 Beta 新特性介绍

    BizTalk2013 Beta于2012年11月6日发布,下面来介绍一下BizTalk 2013 Beta的新特性. [核心更新功能] 1. 与云服务集成 BizTalk 2013 Server提供 ...

  2. 【iCore3 双核心板】例程十九:USBD_MSC实验——虚拟U盘

    实验指导书及代码包下载: http://pan.baidu.com/s/1i4eNbQd iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  3. 【iCore3 双核心板】例程二十二:LAN_UDP实验——以太网数据传输

    实验指导书及代码包下载: http://pan.baidu.com/s/1kTPlJMJ iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  4. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  5. NULL-safe equal

    http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to ,=NULL,NULL=NULL; ...

  6. Android实现推送方式解决方案

    当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如<地震应急通>就需要及时获取服务器上最新的地震信息. 要获取服务器上不定时更新的信息,一般来说有两种方法: 第一 ...

  7. http://blog.csdn.net/ClementAD/article/category/6217187/2

    http://blog.csdn.net/ClementAD/article/category/6217187/2

  8. Windows server 2008 R2搭建主域控制器 + 辅域控制器

    一:实验模拟环境: Zhuyu公司是一个小公司,随着公司状大,公司越来越重视信息化建设,公司考虑到计算机用户权限集中管理及共享资源同步管理, 需要架设一套AD域控服务器,考虑到成本和日后管理问题,计划 ...

  9. cocos2dx 3.x(在Mac平台下利用Eclipse打包安卓apk安装包详细教程)

    最近在学习cocos2dx在MAC上如何打包apk,今天先把安装JDK和ANT的过程记来. 首先,打开终端,输入"java -version" 点击回车后,出现如下提示: 我们的M ...

  10. 使用Go开发HTTP中间件

    原文地址    再web开发的背景下,"中间件"通常意思是"包装原始应用并添加一些额外的功能的应用的一部分".这个概念似乎总是不被人理解,但是我认为中间件非常棒 ...