美文网首页
七、nginx的事件监听(参考《深入剖析Nginx》)(中)

七、nginx的事件监听(参考《深入剖析Nginx》)(中)

作者: 夜雨辉晨 | 来源:发表于2018-01-12 19:52 被阅读0次

     1、在第五篇的末尾,曾提到

    (子进程)将把自己从父进程继承的ngx_channel[1](channel[0]被用于父进程或其它子进程写消息)加入到读事件监听集里。

     实现这个动作的,就是ngx_add_channel_event函数。现在让我们从这个角度来观察一下nginx的事件监听机制。
     这是ngx_add_channel_event(位于ngx_event.c)的主要逻辑代码:

        ngx_int_t
        ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
            ngx_event_handler_pt handler)
        {
            ngx_event_t       *ev, *rev, *wev;
            ngx_connection_t  *c;
    
            c = ngx_get_connection(fd, cycle->log);
          
          //获取事件ev...
    
            ev = (event == NGX_READ_EVENT) ? rev : wev;
    
            ev->handler = handler;
    
            if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
                if (ngx_add_conn(c) == NGX_ERROR) {
                    ngx_free_connection(c);
                    return NGX_ERROR;
                }
    
            } else {
                if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
                    ngx_free_connection(c);
                    return NGX_ERROR;
                }
            }
    
            return NGX_OK;
        }
    

     这里的ngx_add_conn 和ngx_add_event函数,都是第六章中所提到的ngx_event_actions_t 结构体中定义的函数指针。这里主要关注epoll模型。若定义使用epoll模型,则这里的ngx_add_conn 和ngx_add_event将对应ngx_epoll_module.c中的ngx_epoll_add_connection函数和ngx_epoll_add_event函数。

     2、关于epoll

    • 关于ngx_epoll_add_connection函数:

                ngx_epoll_add_connection(ngx_connection_t *c)
        {
            struct epoll_event  ee;
      
            ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
            ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
      
            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
                           "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events);
      
            if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) {
                ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
                              "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd);
                return NGX_ERROR;
            }
      
            c->read->active = 1;
            c->write->active = 1;
      
            return NGX_OK;
        }
      

     关键代码只有一句,

    epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee)

     这里,使用了linux下epoll_ctl注册与c->fd相关联的读事件和写事件。

    • 关于ngx_add_event,逻辑和ngx_epoll_add_connection差不多,也是注册相应flag的epoll事件:

        ee.events = events | (uint32_t) flags;
        ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
        if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
        return NGX_ERROR;
        }
      

    相关文章

      网友评论

          本文标题:七、nginx的事件监听(参考《深入剖析Nginx》)(中)

          本文链接:https://www.haomeiwen.com/subject/rugfoxtx.html