C-libev学习笔记-事件库源码阅读-1

特征

libev是一个用C语言编写的轻量级的事件驱动库,支持多种IO复用接口。
IO接口有:select,poll,epoll,kqueue等

支持的事件:

ev_io; //IO读写
ev_stat; //文件属性
ev_signal;//信号
ev_timer;//定时器
ev_periodic;//绝对定时器
ev_child;//子进程
ev_fork;//fork事件
ev_cleanup;//ev_loop退出触发
ev_idle;//ev_loop空闲触发
ev_embed;//嵌入后台循环
ev_prepare;//ev_loop之前事件
ev_check;//ev_loop之后事件
ev_async;//线程间异步事件

使用示例请看前几篇文章,注释很详细

监视器

libev把事件封装在监视器 watcher 中,watcher是一个结构体,里面保存着与事件相关的信息,包括事件的属性等。
通过注册 watcher 并指定其回调函数,再将监视器注册驱动器即可使用。

常见的宏

EV_P,EV_P_,EV_A,EV_A_
以下代码来自 ev.h <171>

  /* support multiple event loops? */
#if EV_MULTIPLICITY
struct ev_loop;
# define EV_P  struct ev_loop *loop               /* a loop as sole parameter in a declaration */
# define EV_P_ EV_P,                              /* a loop as first of multiple parameters */
# define EV_A  loop                               /* a loop as sole argument to a function call */
# define EV_A_ EV_A,                              /* a loop as first of multiple arguments */
# define EV_DEFAULT_UC  ev_default_loop_uc_ ()    /* the default loop, if initialised, as sole arg */
# define EV_DEFAULT_UC_ EV_DEFAULT_UC,            /* the default loop as first of multiple arguments */
# define EV_DEFAULT  ev_default_loop (0)          /* the default loop as sole arg */
# define EV_DEFAULT_ EV_DEFAULT,                  /* the default loop as first of multiple arguments */
#else
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
# define EV_DEFAULT
# define EV_DEFAULT_
# define EV_DEFAULT_UC
# define EV_DEFAULT_UC_
# undef EV_EMBED_ENABLE
#endif

EV_MULTIPLICITY 显然是一个条件,字面意思 多个事件
表明当允许多个ev_loop示例存在时
ev_loop是主循环,在前几篇的例子中,都是声明了:

ev_loop* main_loop;

看#if部分,有一些宏定义的很奇葩。

# define EV_P  struct ev_loop *loop ;//用EV_P代替struct ev_loop *loop
//也就是说,可以这样写:
void fun(EV_P, ev_io io_w);

# define EV_P_ EV_P,  ;//这个定义要特别注意逗号 ‘,’ 
//也就是说,加上逗号,可以这样写:
void fun(EV_P_ ev_io io_w); //没错,就是省了一个逗号,看起来更像老油条而已

其他部分类似。
对于#else的部分,则是正常的宏定义,第一个参数就是替换为空,即删除

事件相关的宏

libev定义事件很好懂,都是形如 ev_xxx,xxx是事件名,如ev_io,ev_timer
因为C语言是没有类的概念的,那么又想实现多态怎么办呢?
多态的概念不再赘述,而C要实现,无非就是用一些杂七杂八的struct和一些宏定义来实现。

这些监视器里面都包含同一个宏 EV_WATCHER(type)
这个宏的具体定义如下:

/* shared by all watchers */
#define EV_WATCHER(type)			\
  int active; /* private */			\
  int pending; /* private */			\
  EV_DECL_PRIORITY /* private */		\
  EV_COMMON /* rw */				\
  EV_CB_DECLARE (type) /* private */

#define EV_WATCHER_LIST(type)			\
  EV_WATCHER (type)				\
  struct ev_watcher_list *next; /* private */

#define EV_WATCHER_TIME(type)			\
  EV_WATCHER (type)				\
  ev_tstamp at;     /* private */

看懂这些宏就需要一些#define的高级知识了。

先不用管这三行是什么意思

  EV_DECL_PRIORITY /* private */		\
  EV_COMMON /* rw */				\
  EV_CB_DECLARE (type) /* private */

可以理解,EV_WATCHER(type)里面包含 五项:

  int active; /* private */			\
  int pending; /* private */			\
  EV_DECL_PRIORITY /* private */		\
  EV_COMMON /* rw */				\
  EV_CB_DECLARE (type) /* private */

再看具体的监视器,watcher的定义:

/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher
{
  EV_WATCHER (ev_watcher)
} ev_watcher;

这段代码头上注释:/* base class, nothing to see here unless you subclass */,可见,这是在抽象实现类,所以理解源码,必然要学会面向对象的思想。

可见ev_watcher里面包含EV_WATCHER(type),其实两者合一,就是如下:

typedef struct ev_watcher
{
    int active; 
    int pending;
    EV_DECL_PRIORITY /* private */		\
  	EV_COMMON /* rw */				\
  	EV_CB_DECLARE (ev_watcher) /* private */
} ev_watcher;

具体后三位是表示什么,还要找到具体的宏定义。

第一个宏定义在此:

#if EV_MINPRI == EV_MAXPRI
# define EV_DECL_PRIORITY
#elif !defined (EV_DECL_PRIORITY)
# define EV_DECL_PRIORITY int priority;
#endif

又出来了两个宏 EV_MINPRI,EV_MAXPRI,先不管,这个语句的读法就是if-else if-else
总归,EV_DECL_PRIORITY就是 int priority;

不细说了,直接上code

#ifndef EV_COMMON
# define EV_COMMON void *data;
#endif

#ifndef EV_CB_DECLARE
# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
#endif

所以最后,那个watcher就是传说中的!:这个东西,就是一个结构体里面定义了一些内容而已。

typedef struct ev_watcher
{
    int active; 
    int pending;
    int priority;
    void *data;    
    void (*cb)(struct ev_loop *loop, struct ev_watcher *w, int revents);
} ev_watcher;

ok,分析完watcher监视器的内容,那个EV_WATCHER还附带一个 LIST和TIME的宏定义,再来分析一下,ev_watcher里同样也配套定义了list和time部分,如下:

/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher_list
{
  EV_WATCHER_LIST (ev_watcher_list)
} ev_watcher_list;

/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher_time
{
  EV_WATCHER_TIME (ev_watcher_time)
} ev_watcher_time;

根据上述的例子,展开,就是如下:

typedef struct ev_watcher_list
{
    int active; 
    int pending;
    int priority;
    void *data;    
    void (*cb)(struct ev_loop *loop, struct ev_watcher_list *w, int revents);
    struct ev_watcher_list *next;
} ev_watcher_list;

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;

分析了如下几个宏:C-libev学习笔记-事件库源码阅读-1

上一篇:JavaScript 事件委托、事件代理详解


下一篇:从零开始学习3D可视化之事件绑定