libevent代码阅读(7)——“hello-world.c”之 io复用机制的初始化

来源:互联网 发布:淘宝运营个人简历模板 编辑:程序博客网 时间:2024/06/05 21:54

选择完成最适合的io复用机制之后,就要开始进行初始化设置,即调用eventop的init回调函数,以epoll为例,epoll_init的定义如下:

// epoll初始化static void *epoll_init(struct event_base *base){// epoll的文件描述符int epfd;// 用于存放epoll的文件描述符以及一些事件struct epollop *epollop;/* Initialize the kernel queue.  (The size field is ignored since * 2.6.8.) */// 创建epoll文件描述符// 这里直接使用了底层的系统调用,而不是linux提供的api接口if ((epfd = epoll_create(32000)) == -1) {if (errno != ENOSYS)event_warn("epoll_create");return (NULL);}// 当调用exec时 关闭该描述符evutil_make_socket_closeonexec(epfd);// 创建epollop结构if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) {close(epfd);return (NULL);}// 初始化epollop的字段epollop->epfd = epfd;/* Initialize fields */// 初始化epoll事件数组epollop->events = mm_calloc(INITIAL_NEVENT, sizeof(struct epoll_event));if (epollop->events == NULL) {mm_free(epollop);close(epfd);return (NULL);}epollop->nevents = INITIAL_NEVENT;// 如果设置了使用changelist,那么就使用changelist// 使用了changelist可以减少系统调用的次数if ((base->flags & EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST) != 0 ||    ((base->flags & EVENT_BASE_FLAG_IGNORE_ENV) == 0 &&evutil_getenv("EVENT_EPOLL_USE_CHANGELIST") != NULL))base->evsel = &epollops_changelist;// 信号处理器初始化evsig_init(base);return (epollop);}

我们看到epoll_init函数的最后调用了evsig_init,这个函数的作用是初始化信号处理器,它定义如下:

/* * 信号处理器初始化 */intevsig_init(struct event_base *base){/* * Our signal handler is going to write to one end of the socket * pair to wake up our event loop.  The event loop then scans for * signals that got delivered. *//* * 创建用于通知信号到来的管道 * 当程序受到信号的时候,并不直接处理,而是通过管道将其传递到事件多路分发器中 * 这样信号就能够像其他事件那样可以被统一处理了 */if (evutil_socketpair( AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1){#ifdef WIN32/* Make this nonfatal on win32, where sometimes people   have localhost firewalled. */event_sock_warn(-1, "%s: socketpair", __func__);#elseevent_sock_err(1, -1, "%s: socketpair", __func__);#endifreturn -1;}// 调用exec的时,关闭高套接字evutil_make_socket_closeonexec(base->sig.ev_signal_pair[0]);evutil_make_socket_closeonexec(base->sig.ev_signal_pair[1]);// 设置旧的信号处理函数数组和数量base->sig.sh_old = NULL;base->sig.sh_old_max = 0;// 设置套接字为非阻塞evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);evutil_make_socket_nonblocking(base->sig.ev_signal_pair[1]);// 事件处理器赋值event_assign(&base->sig.ev_signal, base, base->sig.ev_signal_pair[1],EV_READ | EV_PERSIST, evsig_cb, base);base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;// 优先级设置event_priority_set(&base->sig.ev_signal, 0);// 保存针对信号的操作(evsigops和epollops一样是一个操作的集合)base->evsigsel = &evsigops;return 0;}


1 0
原创粉丝点击