1. 程式人生 > >libev原始碼分析(一)----基礎結構體

libev原始碼分析(一)----基礎結構體

本篇文章主要分析libev中常用到且十分重要的結構。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; /* rw */

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

    struct ev_watcher_list *next; /* private */

    int fd; /* 檔案描述符 */

    int events; /* 事件型別 */

} ev_io;

ev_timer結構體:

typedef struct ev_timer
{
  int active; /* 是否已經啟用 */
  int pending; /* 是否事件易產生,需要執行回撥 */
  int priority; /* 事件優先順序 */
  void *data; /* rw */
  void (*cb)(struct ev_loop *loop, struct ev_timer *w, int revents); /* 回撥 */
  ev_tstamp at;     /* private */
  ev_tstamp repeat; /* rw */
} ev_timer;

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_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;



每個inotify-id對應的雜湊表的每個節點的結構

typedef struct {

ev_watcher_list* head;

} ANFS;

堆結構的節點

typedef struct {

ev_tstamp at;

ev_watcher_time* w;

} ANHE;