libev IO复用
ev_epoll.c/ev_kqueue.c/ev_poll.c/ev_port.c/ev_select.c都是IO复用的封装,现在以epoll IO复用来讲解;**
ev_epoll.c包含如下函数
void epoll_modify(EV_P_ int fd, int oev, int nev)
void epoll_poll(EV_P_ ev_tstamp timeout)
int inline_size epoll_init(EV_P_ int flags)
void inline_size epoll_destroy(EV_P)
void inline_size epoll_fork(EV_P)
epoll_init
int inline_size
epoll_init (EV_P_ int flags)
{
#ifdef EPOLL_CLOEXEC
backend_fd = epoll_create1 (EPOLL_CLOEXEC);
if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS))
#endif
backend_fd = epoll_create (256);
if (backend_fd < 0)
return 0;
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */
backend_modify = epoll_modify;
backend_poll = epoll_poll;
epoll_eventmax = 64; /* initial number of events receivable per poll */
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
return EVBACKEND_EPOLL;
}
- 其中EV_P_宏是在ev.h文件中定义的:”#define EV_P struct ev_loop *loop”, “#define EV_P_ EV_P,”;
- epoll_init
- backend_fd, backend_modify, backend_poll等宏是在ev_wrap.h中定义;
- 函数中调用epoll_create来创建epoll的文件描述符,并把epoll_modify,epoll_poll赋值为事件主循环结构体的相应成员;
- epoll_modify调用了epoll_ctl(),因此epoll_modify的主要作用是向epoll事件循环中添加/删除/修改相关的事件;
- epoll_poll中调用了epoll_wait(),中epoll的事件队列中去除就绪的事件;