static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { ngx_epoll_conf_t *epcf; epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); if (ep == -1) { ep = epoll_create(cycle->connection_n / 2); if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "epoll_create() failed"); return NGX_ERROR; } #if (NGX_HAVE_EVENTFD) if (ngx_epoll_notify_init(cycle->log) != NGX_OK) { ngx_epoll_module_ctx.actions.notify = NULL; } #endif #if (NGX_HAVE_FILE_AIO) ngx_epoll_aio_init(cycle, epcf); #endif #if (NGX_HAVE_EPOLLRDHUP) ngx_epoll_test_rdhup(cycle); #endif } if (nevents < epcf->events) { if (event_list) { ngx_free(event_list); } event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } nevents = epcf->events; ngx_io = ngx_os_io; ngx_event_actions = ngx_epoll_module_ctx.actions; #if (NGX_HAVE_CLEAR_EVENT) ngx_event_flags = NGX_USE_CLEAR_EVENT #else ngx_event_flags = NGX_USE_LEVEL_EVENT #endif |NGX_USE_GREEDY_EVENT |NGX_USE_EPOLL_EVENT; return NGX_OK; }
// static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) // epoll 模块初始化 {{{ static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { ngx_epoll_conf_t *epcf; epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); if (ep == -1) { // 创建 epoll fd ep = epoll_create(cycle->connection_n / 2); if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "epoll_create() failed"); return NGX_ERROR; } #if (NGX_HAVE_FILE_AIO) // 初始化异步IO ngx_epoll_aio_init(cycle, epcf); #endif } // 事件列表容量不足则重新分配事件列表 if (nevents < epcf->events) { if (event_list) { ngx_free(event_list); } event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } nevents = epcf->events; ngx_io = ngx_os_io; // 初始化事件添加、删除、启用、禁用、事件分发等回调函数 ngx_event_actions = ngx_epoll_module_ctx.actions; #if (NGX_HAVE_CLEAR_EVENT) // 边缘触发 ngx_event_flags = NGX_USE_CLEAR_EVENT #else // 水平触发 ngx_event_flags = NGX_USE_LEVEL_EVENT #endif |NGX_USE_GREEDY_EVENT |NGX_USE_EPOLL_EVENT; return NGX_OK; } // }}}
//主要是完成epoll的相关初始化工作 static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { ngx_epoll_conf_t *epcf; //取得epoll模块的配置结构 epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); //ep是epoll模块定义的一个全局变量,初始化为-1 if (ep == -1) { /* 调用epoll_create 在内核中创建epoll对象。 */ ep = epoll_create(cycle->connection_n / 2); //创一个epoll对象,容量为总连接数的一半 if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "epoll_create() failed"); return NGX_ERROR; } #if (NGX_HAVE_FILE_AIO) ngx_epoll_aio_init(cycle, epcf); #endif } if (nevents < epcf->events) { if (event_list) { ngx_free(event_list); } //event_list存储产生事件的数组 event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } nevents = epcf->events; ngx_io = ngx_os_io; ngx_event_actions = ngx_epoll_module_ctx.actions;//各种工具方法 #if (NGX_HAVE_CLEAR_EVENT) ngx_event_flags = NGX_USE_CLEAR_EVENT //epoll添加这个标志,主要为了实现边缘触发 #else ngx_event_flags = NGX_USE_LEVEL_EVENT //水平触发 #endif |NGX_USE_GREEDY_EVENT //io的时候,直到EAGAIN为止 |NGX_USE_EPOLL_EVENT; //epoll标志 return NGX_OK; }
static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { ngx_epoll_conf_t *epcf; epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); if (ep == -1) { ep = epoll_create(cycle->connection_n / 2); if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "epoll_create() failed"); return NGX_ERROR; } #if (NGX_HAVE_FILE_AIO) ngx_epoll_aio_init(cycle, epcf); #endif } if (nevents < epcf->events) { if (event_list) { ngx_free(event_list); } event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } nevents = epcf->events;//how much event amount we can monitor!!! ngx_io = ngx_os_io; //Here,Set the really socket data read write handler!!! ngx_event_actions = ngx_epoll_module_ctx.actions;//important! Set the Golobal ngx_event_actions as epoll actions!!! #if (NGX_HAVE_CLEAR_EVENT) ngx_event_flags = NGX_USE_CLEAR_EVENT #else ngx_event_flags = NGX_USE_LEVEL_EVENT #endif |NGX_USE_GREEDY_EVENT |NGX_USE_EPOLL_EVENT; return NGX_OK; }
/** * @param [in] cycle * @param [in] timer 定时器精度ngx_timer_resolution * @return NGX_OK|NGX_ERROR * * epoll初始化,创建epollFD */ static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { ngx_epoll_conf_t *epcf; epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); if (ep == -1) { ep = epoll_create(cycle->connection_n / 2); //创建epollFD if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "epoll_create() failed"); return NGX_ERROR; } #if (NGX_HAVE_EVENTFD) //初始化通知notify_fd,将其加入epoll事件中 if (ngx_epoll_notify_init(cycle->log) != NGX_OK) { ngx_epoll_module_ctx.actions.notify = NULL; } #endif #if (NGX_HAVE_FILE_AIO) //异步事件初始化 ngx_epoll_aio_init(cycle, epcf); #endif } if (nevents < epcf->events) { //默认初始化512个 if (event_list) { ngx_free(event_list); } //初始化event_list数组。数组大小是配置项epoll_event的參数 event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } nevents = epcf->events; //事件个数,epoll_wait用到。 /** * \file ../../os/unix/ngx_os.h|c * 指明客户端连接事件触发时,读写I/O的方法。如消息发送与接受 * * \file ../../os/unix/ngx_linux_init.h|c * linux中等同于变量ngx_linux_io值 */ ngx_io = ngx_os_io; /** * ngx_event_actions是个全局的ngx_event_actions_t结构体 * 用于存储不同事件模块的10个函数接口。(添加|删除|...事件、接受|删除|处理..新连接) */ ngx_event_actions = ngx_epoll_module_ctx.actions; //优先使用边缘触发模式 #if (NGX_HAVE_CLEAR_EVENT) ngx_event_flags = NGX_USE_CLEAR_EVENT //使用epoll的边缘触发模式 ET #else ngx_event_flags = NGX_USE_LEVEL_EVENT //使用epoll的水平触发模式 LT #endif |NGX_USE_GREEDY_EVENT |NGX_USE_EPOLL_EVENT; return NGX_OK; }