C代码整洁之道-可配置处理过程


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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值