libev源码分析(一)libev数据结构整理

3718阅读 0评论2012-02-15 图片MM
分类:

 

这里选取的版本为最新版:libev-4.04libev的代码很简练,除了对高效I/O模型等的封装文件,核心文件就两个:ev.hev.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:协调时间 也就是从19701100: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_forkfork行为被检测到,并且在检测子进程之前调用 触发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_asyncev_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;//epollkqueuepollselectport标记

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;

 

上一篇:启动代码和Bootloader的区别和关系介绍
下一篇:STM32 USART使用DMA设置