• libev源代码中关键的一些结构


    这里选取的版本为最新版:libev-4.04。libev的代码很简练,除了对高效I/O模型等的封装文件,核心文件就两个:ev.h和ev.c,其中ev.c大概4000行左右。代码大量用到了宏,并且宏还嵌套了宏,为了便于理解libev的代码,这里对宏进行了还原。

    ev_watcher结构体(其成员为其它结构的公共部分):

    typedef  struct ev_watcher {

    int active;//激活标识

    int pending;//等待事件数

    int priority;//优先级

    void* data;//

    void (*cb)(struct ev_loop* loop, struct ev_watcher *w, int revent);//回调函数

    } ev_watcher;

    ev_watcher_list结构体:

    typedef struct ev_watcher_list {

    int active;

    int pending;

    int prioirty;

    void* data;

    void (*cb)(struct ev_loop* loop, struct ev_watcher_list *w,int revent);

    struct ev_watcher_list *next;//下一个watcher

    } ev_watcher_list;

    ev_watcher_time 结构体:

    typedef struct ev_watcher_time

    {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_watcher_time *w,int revents);

    ev_tstamp at;//

    } ev_watcher_time;

    ev_io结构体:

    typedef struct ev_io {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_io *w,int revents);

    struct ev_watcher_list *next;

    int fd;//文件描述符

    int events;//事件类型

    } ev_io;

    ev_io在触发EV_READ或者是EV_WRITE被调用

    ev_timer结构体:

    typedef struct ev_timer {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_timer *w,int revents);

    ev_tstamp at;//

    ev_tstamp repeat;//

    } ev_timer;

    ev_timer在特定的时间调用,并周期性进行,其基于单调时钟
    (PS:单调时钟:此时间来源会严格的线性递增,一般linux会使用系统正常运行时间来表示,也就是从开机开始算起)触发事件EV_TIMEOUT

    ev_periodic结构体:

    typedef struct ev_periodic {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_periodic *w,int revents);

    ev_tstamp at;//

    ev_tstamp offset;//

    ev_tstamp interval;//

    ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now);//

    } ev_periodic;

    ev_periodic在特定的时间调用,可能会在定期间隔反复调用,其基于UTC时间
    (PS:UTC:协调时间 也就是从1970年1月1日00:00:00开始记时)触发事件EV_PERIODIC

    ev_signal结构体:

    typedef struct ev_signal {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_signal *w,int revents);

    struct ev_watcher_list *next;

    int signum;//

    } ev_signal;

    ev_signal当接收到指定的信号时调用 触发事件EV_SIGNAL

    ev_child结构体:

    typedef struct ev_child {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_child *w,int revents);

    struct ev_watcher_list *next;

    int flag;//

    int pid;//

    int rpid;//

    int rstatus;//

    } ev_child;

    ev_child当接收到SIGCHLD信号并且waitpid表示了给出的pid时调用 触发EV_CHILD事件
    其不支持优先级

    ev_stat结构体:

    typedef struct ev_stat {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_stat *w,int revents);

    struct ev_watcher_list *next;

    ev_timer timer;//

    ev_tstamp interval;//

    const char *path;//

    ev_statdata prev;//

    ev_statdata attr;//

    int wd;//

    } ev_stat;

    ev_stat当每次指定的路径状态数据发生改变时调用 触发EV_STAT

    ev_idle结构体:

    typedef struct ev_idle {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_idle *w,int revents);

    } ev_idle;

    ev_idle当啥事情都不需要做的时候调用,用来保持进程远离阻塞 触发EV_IDLE

    ev_prepare结构体:

    typedef struct ev_prepare {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_prepare *w,int revents);

    } ev_prepare;

    ev_prepare每次执行mainloop主循环,在主循环之前调用 触发EV_PREPARE

    ev_check结构体:

    typedef struct ev_check {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_check *w,int revents);

    } ev_check;

    ev_check每次执行mainloop主循环,在主循环之后调用 触发EV_CHECK

    ev_fork结构体:

    typedef struct ev_fork {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop,struct ev_fork *w,int revents);

    } ev_fork;

    ev_fork在fork行为被检测到,并且在检测子进程之前调用 触发EV_FORK

    ev_cleanup结构体:

    typedef struct ev_cleanup {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop,struct ev_cheanup *w,int revents);

    } ev_cleanup;

    ev_cleanup在主循被销毁之后调用 触发EV_CLEANUP

    ev_embed结构体:

    typedef struct ev_embed {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop,struct ev_embed *w,int revents);

    struct ev_loop* other;//

    ev_io io;

    ev_prepare prepare;

    ev_check check;

    ev_timer timer;

    ev_periodic periodic;

    ev_idle idle;

    ev_fork fork;

    #if EV_CLEANUP_ENABLE

      ev_cleanup cleanup;    /* unused */

    #endif

    } ev_embed;

    ev_embed用于将一个事件循环嵌套到另一个中,当事件循环处理事件的时候被调用

    ev_async结构体:

    typedef struct ev_async {

    int active;

    int pending;

    int priority;

    void* data;

    void (*cb)(struct ev_loop *loop, struct ev_async *w, int revents);

    sig_atomic_t volatile sent;//

    } ev_async;

    ev_async当ev_async_send通过watcher调用时调用,触发EV_ASYNC

    ev_any_watcher结构:

    union ev_any_watcher {

    struct ev_watcher w;

    struct ev_watcher_list wl;

    struct ev_io io;

    struct ev_timer timer;

    struct ev_periodic periodic;

    struct ev_signal signal;

    struct ev_child child;

    #if EV_STAT_ENABLE

    struct ev_stat stat;

    #endif

    #if EV_IDLE_ENABLE

    struct ev_idle idle;

    #endif

    struct ev_prepare prepare;

    struct ev_check check;

    #if EV_FORK_ENABLE

    struct ev_fork fork;

    #endif

    #if EV_CLEANUP_ENABLE

    struct ev_cleanup cleanup;

    #endif

    #if EV_EMBED_ENABLE

    struct ev_embed embed;

    #endif

    #if EV_ASYNC_ENABLE

    struct ev_async async;

    #endif

    };

    该结构的存在用以强制类似结构的布局

    ev_loop结构体(事件循环的主体):

    struct ev_loop

    {

        ev_tstamp ev_rt_now;

        #define ev_rt_now ((loop)->ev_rt_now)

        #define VAR(name,decl) decl;

          #include "ev_vars.h" //包含众多成员

        #undef VAR

     };

    ev_loop的一些成员:

    ev_tstamp now_floor; /* last time we refreshed rt_time */

    ev_tstamp mn_now; //当前单调时间,系统开机时间

    ev_tstamp rtmn_diff; /* difference realtime - monotonic time */

    unsigned int origflags;//

    int backend;//epoll、kqueue、poll、select、port标记

    int activecnt;//激活事件总数

    int backend_fd;//对于epoll,为epoll_create返回的描述符

    int * fdchanges;//事件队列

    int fdchangemax;//当前最大事件数

    int fdchangecnt;//事件数

    ANPENDING *pendings [NUMPRI];//待处理队列

    int pendingmax [NUMPRI];//当前最大等待事件的数量

    int pendingcnt [NUMPRI];//记录每个优先级的数量

    文件描述符信息结构

    typedef struct{

    ev_watcher_list* head; //监听者链表

    unsigned char events; //监听的事件

    unsigned char reify;//状态位 用来表示具体是EV_ANFD_REIFY还是EV_IOFDSET

    unsigned char emask;//epoll用来保存内核mask的值

    unsigned char unused;//同名字

    #if EV_USE_EPOLL

    unsigned int egen;//

    #endif

    #if EV_SELECT_ISWINSOCKET || EV_USE_IOCP

    SOCKET handle;//

    #endif

    #if EV_USE_IOCP

    OVERLAPPED or,ow;//

    #endif

    } ANFD;

    指定等待事件的监听者结构

    typedef struct {

    ev_watcher* w;

    int events;

    } ANPENDING;

    每个inotify-id对应的哈希表的每个节点的结构

    typedef struct {

    ev_watcher_list* head;

    } ANFS;

    堆结构的节点

    typedef struct {

    ev_tstamp at;

    ev_watcher_time* w;

    } ANHE;

  • 相关阅读:
    使用SuperWebSocket 构建实时 Web 应用
    slam for Windows 库安装及应用libfreenect2
    《SLAM十四讲》g2o_custombundle在windows轻松调通
    windows下命令行查看库依赖
    zend studio控制台中文乱码
    http协议转
    mysql 字段 增删改
    PHP内部函数
    分层设计
    SecureCRT上传和下载
  • 原文地址:https://www.cnblogs.com/Huayuan/p/3056709.html
Copyright © 2020-2023  润新知