libevent源码阅读笔记

来源:互联网 发布:域名一定要备案吗 编辑:程序博客网 时间:2024/06/13 10:32

1.概述
libvent是基于事件驱动的开源框架.记录一下看源码学到的东西.
2. 核心结构体.

struct event {    TAILQ_ENTRY (event) ev_next;    TAILQ_ENTRY (event) ev_active_next;    TAILQ_ENTRY (event) ev_signal_next;    unsigned int min_heap_idx;  /* for managing timeouts */    struct event_base *ev_base;    int ev_fd;    short ev_events;    short ev_ncalls;    short *ev_pncalls;  /* Allows deletes in callback */    struct timeval ev_timeout;    int ev_pri;     /* smaller numbers are higher priority */    void (*ev_callback)(int, short, void *arg);    void *ev_arg;    int ev_res;     /* result passed to event callback */    int ev_flags;};

这个结构体是libevent 对于事件的抽象,一个需要监听的事件在内存中一定有一个这样的结构体与之对应. 某一时刻系统中有很多这样的结构体存在, 那就需要将这些事件按照数据结构组织起来,libevent中使用双向队列和堆来组织这些event.
前面几个字段是能让事件以队列和堆组织起来,所必须要的字段.
后面的字段包括该事件的回调函数,回调函数的参数,ev_flags标志了该事件在哪个队列上,ev_fd监听的套接字描述符,ev_events表示感兴趣的动作,如套接字可读,套接字可写,超时等.

struct event_base {    const struct eventop *evsel;    void *evbase;    int event_count;        /* counts number of total events */    int event_count_active; /* 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;    int nactivequeues;    /* signal handling info */    struct evsignal_info sig;    struct event_list eventqueue;    struct timeval event_tv;    struct min_heap timeheap;    struct timeval tv_cache;};
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;};

eventop 是封装select poll等操作的结构体,
event_base 结构体的第一个字段就是指向这张操作表的指针,event_base的第二个字段指向 select完成工作所需要的一些必要东西,比如select函数调用时需要fd_set 来向内核告诉我们想要监听的套接字等,所以需要一个结构来帮忙储存这些东西,因此event_base的第二个字段就指向这个结构体.
换个角度,eventop其实是一张虚表,event_base的第二个字段其实是指向子类的字段,event_base的其他字段则是父类所共有的部分.而且,向外部屏蔽了底层select 和poll epoll的实现细节,所有的子类向父类提供相同的接口,父类中的eventop由select实现,则父类中提供的api就调用select版本来完成工作,eventop由epoll实现则父类中提供的api就调用epoll版本来完成工作,这是C版本的多态加信息隐藏,
event_base 提供的api主要完成两部分的工作: 数据结构的更新 和对子类(select epoll)的更新, 子类的更新通过子类提供的api完成. 例如当添加一个event时,会把该event添加到event_base 的eventqueue字段的队列中,而且调用eventop的add方法,将该事件的文件描述符添加到 字段evbase指向的结构体的fdset字段中 .

3.总结
libevent的工作流程大致了解了,get到的主要点是多态的应用和数据结构管理事件.