C-libev学习笔记-事件库源码阅读2-各种监视器源码解析

‘基类’与‘派生类’

基类在上文提到,是

/* 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 */
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;

这并不是真正的类,只是抽象理解
派生类是:

ev_io

/* invoked when fd is either EV_READable or EV_WRITEable */
/* revent EV_READ, EV_WRITE */
typedef struct ev_io
{
  EV_WATCHER_LIST (ev_io)

  int fd;     /* ro */
  int events; /* ro */
} ev_io;

可见ev_io包含了重定义 EV_WATCHER_LIST (),所以就有了基类的属性,自带的属性是 int fd 和 int events,事件第一行的解释为:当fd发生读或写的时候,事件读或事件写触发。fd在linux里面比较形象是文件描述符,它就代表一个事件,当fd发生了读写事件的时候,就会调用相应的函数,并且会把这个事件加入到事件链表中。

ev_timer, ev_periodic

/* invoked after a specific time, repeatable (based on monotonic clock) */
/* revent EV_TIMEOUT */
typedef struct ev_timer
{
  EV_WATCHER_TIME (ev_timer)

  ev_tstamp repeat; /* rw */
} ev_timer;

/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
/* revent EV_PERIODIC */
typedef struct ev_periodic
{
  EV_WATCHER_TIME (ev_periodic)

  ev_tstamp offset; /* rw */
  ev_tstamp interval; /* rw */
  ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
} ev_periodic;

这两个事件监视器类似,一个是相对时间,一个是绝对时间。
ev_timer:在特定时间后调用,可重复(基于单调时钟),
ev_periodic:在某个特定的时间调用,可能会定期重复(基于UTC)
从继承上看,他们都继承EV_WATCHER_TIME父类,实现上来看,ev_periodic要更为复杂,从其他博客得知有一个区别:
ev_timer是相对时间,设置10s,那么就会在10s后触发。
ev_periodic是绝对时间,设置10s,如果修改系统时间延后一年,那它就会在一年10s后触发。
此外,这两个时间监视器并没有放在监视器的链表中。

ev_signal:

/* invoked when the given signal has been received */
/* revent EV_SIGNAL */
typedef struct ev_signal
{
  EV_WATCHER_LIST (ev_signal)

  int signum; /* ro */
} ev_signal;

当收到信号时,触发。

ev_child:

/* invoked when sigchld is received and waitpid indicates the given pid */
/* revent EV_CHILD */
/* does not support priorities */
typedef struct ev_child
{
  EV_WATCHER_LIST (ev_child)

  int flags;   /* private */
  int pid;     /* ro */
  int rpid;    /* rw, holds the received pid */
  int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
} ev_child;

加入监视器链表中,结构体内保存一些线程信息。

ev_stat:

#if EV_STAT_ENABLE
/* st_nlink = 0 means missing file or other error */
# ifdef _WIN32
typedef struct _stati64 ev_statdata;
# else
typedef struct stat ev_statdata;
# endif

/* invoked each time the stat data changes for a given path */
/* revent EV_STAT */
typedef struct ev_stat
{
  EV_WATCHER_LIST (ev_stat)

  ev_timer timer;     /* private */
  ev_tstamp interval; /* ro */
  const char *path;   /* ro */
  ev_statdata prev;   /* ro */
  ev_statdata attr;   /* ro */

  int wd; /* wd for inotify, fd for kqueue */
} ev_stat;
#endif

ev_stat是一个条件定义。
出现第一个宏是EV_STAT_ENABLE字面意思是支持文件系统?
这个宏出现在这些地方
在这里插入图片描述
转到宏定义:

#ifndef EV_STAT_ENABLE
# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
#endif

可见EV_STAT_ENABLE 用 EV_FEATURE_WATCHERS宏替换,查看EV_FEATURE_WATCHERS:

#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)

它是EV_FEATURES 和 16的 ‘与’值
查看EV_FEATURES:

#ifndef EV_FEATURES
# if defined __OPTIMIZE_SIZE__
#  define EV_FEATURES 0x7c
# else
#  define EV_FEATURES 0x7f
# endif
#endif

它实现了对32位系统文件和64位系统文件的支持。
结构体里还有一个ev_tstamp类型:

typedef double ev_tstamp;

ev_tstamp就是double类型

ev_idle:

#if EV_IDLE_ENABLE
/* invoked when the nothing else needs to be done, keeps the process from blocking */
/* revent EV_IDLE */
typedef struct ev_idle
{
  EV_WATCHER (ev_idle)
} ev_idle;
#endif

当不需要执行其他操作时调用,防止进程阻塞

ev_prepare:

/* invoked for each run of the mainloop, just before the blocking call */
/* you can still change events in any way you like */
/* revent EV_PREPARE */
typedef struct ev_prepare
{
  EV_WATCHER (ev_prepare)
} ev_prepare;

在阻塞之前调用

ev_check:

/* invoked for each run of the mainloop, just after the blocking call */
/* revent EV_CHECK */
typedef struct ev_check
{
  EV_WATCHER (ev_check)
} ev_check;

在阻塞之后调用

ev_fork:

#if EV_FORK_ENABLE
/* the callback gets invoked before check in the child process when a fork was detected */
/* revent EV_FORK */
typedef struct ev_fork
{
  EV_WATCHER (ev_fork)
} ev_fork;
#endif

条件事件,EV_FORK_ENABLE:

#ifndef EV_FORK_ENABLE
# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
#endif

fork进程的时候调用

ev_cleanup:

#if EV_CLEANUP_ENABLE
/* is invoked just before the loop gets destroyed */
/* revent EV_CLEANUP */
typedef struct ev_cleanup
{
  EV_WATCHER (ev_cleanup)
} ev_cleanup;
#endif

条件定义,EV_CLEANUP_ENABLE:

#ifndef EV_CLEANUP_ENABLE
# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
#endif

在循环被破坏之前调用

ev_embed:

#if EV_EMBED_ENABLE
/* used to embed an event loop inside another */
/* the callback gets invoked when the event loop has handled events, and can be 0 */
typedef struct ev_embed
{
  EV_WATCHER (ev_embed)

  struct ev_loop *other; /* ro */
  ev_io io;              /* private */
  ev_prepare prepare;    /* private */
  ev_check check;        /* unused */
  ev_timer timer;        /* unused */
  ev_periodic periodic;  /* unused */
  ev_idle idle;          /* unused */
  ev_fork fork;          /* private */
#if EV_CLEANUP_ENABLE
  ev_cleanup cleanup;    /* unused */
#endif
} ev_embed;
#endif
#ifndef EV_EMBED_ENABLE
# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
#endif

将循环事件嵌入到另一个循环事件中

ev_async:

#if EV_ASYNC_ENABLE
/* invoked when somebody calls ev_async_send on the watcher */
/* revent EV_ASYNC */
typedef struct ev_async
{
  EV_WATCHER (ev_async)

  EV_ATOMIC_T sent; /* private */
} ev_async;

# define ev_async_pending(w) (+(w)->sent)
#endif
#ifndef EV_ASYNC_ENABLE
# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
#endif

ev_any_watcher:

这是一个共同体声明,同一时刻一个共同体里面只能有一个变量,共同体里面的变量共用一个存储空间,存储空间取共同体里最大的变量所需要的空间。

/* the presence of this union forces similar struct layout */
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.h头文件里面关于监视器的声明就基本结束了,还剩下一堆的枚举和API的定义,其实对于一个库,掌握变量的定义和API函数的定义功能就可以掌握。
到后面还会阅读ev++.h,其实ev++.h和ev.h是相互包含的,文件的第二句便是。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子砰砰枪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值