The selected version is the latest version: libev-4.04. The libev code is concise. In addition to encapsulation files such as the efficient I/O model, the core files are ev. h and ev. c, of which ev. c contains about 4000 lines. A large number of macros are used in the code, and macros are nested. To facilitate understanding of libev code, the macro is restored here.
The ev_watcher struct (its member is the public part of another structure ):
Typedef struct ev_watcher {
Int active; // activation ID
Int pending; // Number of waiting events
Int priority; // priority
Void * data ;//
Void (* cb) (struct ev_loop * loop, struct ev_watcher * w, int revent); // callback function
} Ev_watcher;
Ev_watcher_list struct:
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; // The next watcher
} Ev_watcher_list;
Ev_watcher_time struct:
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 ;//
} Ev_watcher_time;
Ev_io struct:
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; // file descriptor
Int events; // event type
} Ev_io;
Ev_io is called when EV_READ or EV_WRITE is triggered.
Ev_timer struct:
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 ;//
Ev_tstamp repeat ;//
} Ev_timer;
Ev_timer is called at a specific time and periodically executed. It is based on a monotonous clock.
(PS: monotonous clock: The time source will increase linearly. Generally, linux uses the normal running time of the system, that is, starting from the start of the boot) to trigger the event EV_TIMEOUT.
Ev_periodic struct:
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 ;//
Ev_tstamp offset ;//
Ev_tstamp interval ;//
Ev_tstamp (* reschedule_cb) (struct ev_periodic * w, ev_tstamp now );//
} Ev_periodic;
Ev_periodic is called at a specific time and may be called at regular intervals. It is based on UTC time.
(PS: UTC: the coordination time, that is, the start time of 00:00:00 on January 1, January 1, 1970) triggers the event ev_periodic.
Ev_signal struct:
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 calls the trigger event ev_signal when a specified signal is received.
Ev_child struct:
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 calls the ev_child event when the sigchld signal is received and the waitpid represents the given PID.
It does not support priority.
Ev_stat struct:
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 is called to trigger EV_STAT every time the specified path state data changes.
Ev_idle struct:
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 is called when nothing needs to be done. It is used to keep the process away from blocking and trigger EV_IDLE.
Ev_prepare struct:
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 is called before the main loop to trigger ev_prepare every time mainloop is executed.
Ev_check struct:
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: The main loop of mainloop is executed each time, and ev_check is triggered after the main loop.
Ev_fork struct:
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 is detected in fork behavior and called to trigger EV_FORK before detecting the sub-process
Ev_cleanup struct:
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 is called to trigger EV_CLEANUP after the primary cycle is destroyed.
Ev_embed struct:
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 is used to nest an event loop into another, which is called when the event is processed cyclically.
Ev_async struct:
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 is called when ev_async_send is called through watcher, triggering EV_ASYNC
Ev_any_watcher structure:
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
};
This structure is used to force a layout similar to the structure.
Ev_loop struct (subject of the event 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" // contains many Members
# UNDEF VaR
};
Some ev_loop members:
Ev_tstamp now_floor;/* last time we refreshed rt_time */
Ev_tstamp mn_now; // current monotonous time, system boot time
Ev_tstamp rtmn_diff;/* difference realtime-monotonic time */
Unsigned int origflags ;//
Int backend; // epoll, kqueue, poll, select, and port flag
Int activecnt; // The total number of activation events.
Int backend_fd; // For epoll, It is the descriptor returned by epoll_create.
Int * fdchanges; // event queue
Int fdchangemax; // current maximum number of events
Int fdchangecnt; // number of events
ANPENDING * pendings [NUMPRI]; // queue to be processed
Int pendingmax [NUMPRI]; // current maximum number of waiting events
Int pendingcnt [NUMPRI]; // number of records per priority
File descriptor Information Structure
Typedef struct {
Ev_watcher_list * head; // listener linked list
Unsigned char events; // listener event
Unsigned char reify; // The status bit indicates whether it is EV_ANFD_REIFY or EV_IOFDSET.
Unsigned char emask; // epoll is used to save the kernel mask Value
Unsigned char unused; // same name
# 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;
Listener structure for waiting events
Typedef struct {
Ev_watcher * w;
Int events;
} ANPENDING;
Structure of each node in the hash table corresponding to each inotify-id
Typedef struct {
Ev_watcher_list * head;
} Anfs;
Heap Node
Typedef struct {
Ev_tstamp;
Ev_watcher_time * W;
} Anhe;