void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
ngx_uint_t flags;
ngx_msec_t timer, delta;
......
delta = ngx_current_msec;
// 处理事件ngx_epoll_process_events
(void) ngx_process_events(cycle, timer, flags);
delta = ngx_current_msec - delta;
......
// 这个是ACCEPT 事件队列指针
if (ngx_posted_accept_events) {
ngx_event_process_posted(cycle, &ngx_posted_accept_events);
}
......
// 这个是POST 事件队列指针
if (ngx_posted_events) {
if (ngx_threaded) {
ngx_wakeup_worker_thread(cycle);
} else {
ngx_event_process_posted(cycle, &ngx_posted_events);
}
}
}
#define ngx_process_events ngx_event_actions.process_events
Ngx_aio_module.c (src\event\modules): ngx_event_actions = ngx_aio_module_ctx.actions;
Ngx_devpoll_module.c (src\event\modules): ngx_event_actions = ngx_devpoll_module_ctx.actions;
Ngx_epoll_module.c (src\event\modules): ngx_event_actions = ngx_epoll_module_ctx.actions;
Ngx_eventport_module.c (src\event\modules): ngx_event_actions = ngx_eventport_module_ctx.actions;
Ngx_kqueue_module.c (src\event\modules): ngx_event_actions = ngx_kqueue_module_ctx.actions;
Ngx_poll_module.c (src\event\modules): ngx_event_actions = ngx_poll_module_ctx.actions;
Ngx_rtsig_module.c (src\event\modules): ngx_event_actions = ngx_rtsig_module_ctx.actions;
Ngx_rtsig_module.c (src\event\modules): ngx_event_actions.process_events = ngx_rtsig_process_overflow;
Ngx_rtsig_module.c (src\event\modules): ngx_event_actions.process_events = ngx_rtsig_process_events;
Ngx_select_module.c (src\event\modules): ngx_event_actions = ngx_select_module_ctx.actions;
Ngx_win32_select_module.c (src\event\modules): ngx_event_actions = ngx_select_module_ctx.actions;
static ngx_int_t
ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{
ngx_epoll_conf_t *epcf;
......
nevents = epcf->events;
ngx_io = ngx_os_io;
// 注册EPOLL 事件处理函数
ngx_event_actions = ngx_epoll_module_ctx.actions;
......
return NGX_OK;
}
ngx_module_t ngx_epoll_module = {
NGX_MODULE_V1,
&ngx_epoll_module_ctx, /* module context */
ngx_epoll_commands, /* module directives */
NGX_EVENT_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
typedef struct {
ngx_str_t *name;
void *(*create_conf)(ngx_cycle_t *cycle);
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
ngx_event_actions_t actions;
} ngx_event_module_t;
typedef struct {
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*add_conn)(ngx_connection_t *c);
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
void (*done)(ngx_cycle_t *cycle);
} ngx_event_actions_t;
ngx_event_module_t ngx_epoll_module_ctx = {
&epoll_name,
ngx_epoll_create_conf, /* create configuration */
ngx_epoll_init_conf, /* init configuration */
{
ngx_epoll_add_event, /* add an event */
ngx_epoll_del_event, /* delete an event */
ngx_epoll_add_event, /* enable an event */
ngx_epoll_del_event, /* disable an event */
ngx_epoll_add_connection, /* add an connection */
ngx_epoll_del_connection, /* delete an connection */
NULL, /* process the changes */
ngx_epoll_process_events, /* process the events */
ngx_epoll_init, /* init the events */
ngx_epoll_done, /* done the events */
}
};
static ngx_int_t
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
int events;
uint32_t revents;
ngx_int_t instance, i;
ngx_uint_t level;
ngx_err_t err;
ngx_event_t *rev, *wev, **queue;
ngx_connection_t *c;
/* NGX_TIMER_INFINITE == INFTIM */
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll timer: %M", timer);
// ep : epoll_create
// event_list:用于回传时间的数组
// nevents:每次能够处理的最大数目的事件
// events:返回值表示有事件的描述符个数
events = epoll_wait(ep, event_list, (int) nevents, timer);
// 返回值等于-1 吗,
err = (events == -1) ? ngx_errno : 0;
// 若需更新时间标志置位或有告警,则更新系统时间
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
// 若有错误
if (err) {
// 若是系统终端日志级别设置为LOG_INFO
if (err == NGX_EINTR) {
if (ngx_event_timer_alarm) {
ngx_event_timer_alarm = 0;
return NGX_OK;
}
level = NGX_LOG_INFO;
} else {
// 或设置为ALERT
level = NGX_LOG_ALERT;
}
// 写日志,退出
ngx_log_error(level, cycle->log, err, "epoll_wait() failed");
return NGX_ERROR;
}
// 返回事件数值为0,异常
if (events == 0) {
if (timer != NGX_TIMER_INFINITE) {
return NGX_OK;
}
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"epoll_wait() returned no events without timeout");
return NGX_ERROR;
}
// 加锁
ngx_mutex_lock(ngx_posted_events_mutex);
for (i = 0; i < events; i++)
{
c = event_list[i].data.ptr;
// ???
instance = (uintptr_t) c & 1;
// ???
c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1);
// 获取连接读事件
rev = c->read;
// 检查FD
if (c->fd == -1 || rev->instance != instance) {
/*
* the stale event from a file descriptor
* that was just closed in this iteration
*/
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll: stale event %p", c);
continue;
}
// 获取事件
revents = event_list[i].events;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll: fd:%d ev:%04XD d:%p",
c->fd, revents, event_list[i].data.ptr);
if (revents & (EPOLLERR|EPOLLHUP)) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll_wait() error on fd:%d ev:%04XD",
c->fd, revents);
}
#if 0
if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"strange epoll_wait() events fd:%d ev:%04XD",
c->fd, revents);
}
#endif
if ((revents & (EPOLLERR|EPOLLHUP))
&& (revents & (EPOLLIN|EPOLLOUT)) == 0)
{
/*
* if the error events were returned without EPOLLIN or EPOLLOUT,
* then add these flags to handle the events at least in one
* active handler
*/
revents |= EPOLLIN|EPOLLOUT;
}
// 读事件
if ((revents & EPOLLIN) && rev->active) {
if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
rev->posted_ready = 1;
} else {
// 接受事件准备就绪
rev->ready = 1;
}
if (flags & NGX_POST_EVENTS) {
// 若是接受事件则
queue = (ngx_event_t **) (rev->accept ?
&ngx_posted_accept_events : &ngx_posted_events);
// 若是ACCEPT 事件将事件加入到ACCETP 事件队列
// 若是读数据事件则加入POST 事件队列
ngx_locked_post_event(rev, queue);
} else {
// 处理接收事件
rev->handler(rev);
}
}
wev = c->write;
// 写事件
if ((revents & EPOLLOUT) && wev->active) {
if (c->fd == -1 || wev->instance != instance) {
/*
* the stale event from a file descriptor
* that was just closed in this iteration
*/
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll: stale event %p", c);
continue;
}
if (flags & NGX_POST_THREAD_EVENTS) {
wev->posted_ready = 1;
} else {
wev->ready = 1;
}
if (flags & NGX_POST_EVENTS) {
// 将事件加入到POST 事件队列
ngx_locked_post_event(wev, &ngx_posted_events);
} else {
// 处理发送事件
wev->handler(wev);
}
}
}
ngx_mutex_unlock(ngx_posted_events_mutex);
return NGX_OK;
}