zoukankan      html  css  js  c++  java
  • Libevent源码分析—event, event_base

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

    1.event:

    struct event {
            TAILQ_ENTRY (event) ev_next;  //I/O事件
            TAILQ_ENTRY (event) ev_active_next;  //所有激活事件的链表
            TAILQ_ENTRY (event) ev_signal_next;  //Signal事件
            //定时事件在小根堆中的索引
            unsigned int min_heap_idx;      /* for managing timeouts */
            struct event_base *ev_base; //event所属的Reactor
            int ev_fd; //IO事件:绑定的文件描述符;Signal事件:绑定的信号
            short ev_events;  //I/O、信号、定时器
            short ev_ncalls;  //调用回调函数的次数
            short *ev_pncalls; //指向ev_ncalls      /* Allows deletes in callback */
            struct timeval ev_timeout;  //定时事件的超时值
            int ev_pri; //event优先级               /* smaller numbers are higher priority */
            void (*ev_callback)(int, short, void *arg);  //回调函数:ev_fd, ev_events, ev_arg
            void *ev_arg;
            int ev_res;  //调用回调函数时,传递给回调函数,保存回调函数的返回值           /* result passed to event callback */
            int ev_flags;  //event的当前状态
    };
    从event这个结构体我们可以看到libevent将I/O、信号、定时器3种事件统一封装成一个event来对待。
    各成员都已详细注释,其中ev_events取值有:
    // event.ev_events
    #define EV_TIMEOUT      0x01
    #define EV_READ         0x02
    #define EV_WRITE        0x04
    #define EV_SIGNAL       0x08
    //永久事件
    #define EV_PERSIST      0x10    /* Persistant event */

    ev_flags取值有:

    // event.ev_flags
    // event在time堆中
    #define EVLIST_TIMEOUT  0x01
    //event在已注册事件链表中
    #define EVLIST_INSERTED 0x02
    #define EVLIST_SIGNAL   0x04
    //event在激活链表中
    #define EVLIST_ACTIVE   0x08
    #define EVLIST_INTERNAL 0x10
    //event已被初始化
    #define EVLIST_INIT     0x80
    /* EVLIST_X_ Private space: 0x1000-0xf000 */
    #define EVLIST_ALL      (0xf000 | 0x9f)

    2.event_base:

    struct event_base {
            const struct eventop *evsel;  //I/O多路复用机制的封装,eventops[]数组中一项
            void *evbase;  //I/O多路复用机制的一个实例,执行具体任务
            int event_count; //该event_base上的总的event            /* counts number of total events */
            int event_count_active;  //该event_base上的总的激活的event /* counts number of active events */
            int event_gotterm;              /* Set to terminate loop */
            int event_break;                /* Set to terminate loop immediately */
            /* active event management */
            struct event_list **activequeues; //指针数组,activequeues[priority]指向优先级为priority的链表
            int nactivequeues;
            /* signal handling info */
            struct evsignal_info sig;  //管理Signal事件
            struct event_list eventqueue; //链表,保存了所有注册事件event的指针
            struct timeval event_tv;  //时间管理
            struct min_heap timeheap;  //管理定时事件的小根堆
            struct timeval tv_cache;  //时间管理
    };
    其中eventop结构体和evbase是保存了I/O多路复用机制相关信息。evsel会调用init()去初始化evbase。
    eventop结构体如下:
    struct eventop {
            const char *name;
            void *(*init)(struct event_base *);  //初始化
            int (*add)(void *, struct event *);  //注册事件
            int (*del)(void *, struct event *);  //删除事件
            int (*dispatch)(struct event_base *, void *, struct timeval *);  //事件分发
            void (*dealloc)(struct event_base *, void *);  //注销,释放资源
            /* set if we need to reinitialize the event base */
            int need_reinit;
    };
    脚踏实地、积极思考
  • 相关阅读:
    Node.js模块风格在浏览器中的尝试
    Node.js的模块写法入门
    JavaScript中“+”的陷阱(续)
    Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
    使用r.js压缩整个项目的JavaScript文件
    拥抱模块化的JavaScript
    图片播放(3)
    JavaScript中“+”的陷阱
    仅IE6/7浏览器SPAN元素包含块级元素会使SPAN的背景色显示
    JavaScript模态对话框类(拖拽时动画)
  • 原文地址:https://www.cnblogs.com/zxiner/p/6919036.html
Copyright © 2011-2022 走看看