Nginx 소스 코드 분석 - 이벤트 이벤트 편 - Nginx 이벤트 모듈 개관

9559 단어
앞에서 우 리 는 을 설명 했다.  실제로 일부 사건 모듈 의 개념 이 언급 되 었 다.세 심하게 보면 Nginx 의 사건 은 모두 nginx이벤트. c 파일 의 ngxprocess_events_and_timers 프로 세 스 이벤트 분배 기 이 함수 가 시 작 됐 습 니 다.
이 장 을 시작 으로 우 리 는 Nginx 의 이벤트 모듈 을 상세 하 게 분석 할 것 이다.만약 당신 이 인터넷 IO 모델 에 대해 잘 모 르 는 것 이 있다 면, 먼저 이 익숙 함 을 참고 하 는 것 도 좋 습 니 다. 전재 와 축적 시리즈 - 네트워크 IO 모델
리 눅 스 의 epoll 모델 에 대해 잘 모 르 신다 면 epoll 의 원 리 를 먼저 배 워 보 세 요. 제 글 인 '리 눅 스 c 개발 - libevent' 도 참고 하 세 요.
모든 준비 가 다 되면 우 리 는 시작 할 수 있다.
이벤트 모듈 개관
1. ngx_event. c: 이 파일 은 주로 Nginx 이벤트 이벤트 이벤트 모듈 의 핵심 코드 를 설치 합 니 다.
포함: 프로 세 스 이벤트 배포 기 (ngx process events and timers), 이벤트 모듈 의 모듈 과 설정, 모듈 초기 화 / 설정 초기 화 등 이벤트 모듈 초기 화 핵심 함수.
2. ngx_event_timer. c: 타이머 이벤트 관리.타이머 코드 를 주로 설치 합 니 다.
3. ngx_event_poted. c: accept 잠 금 을 가 져 오 는 프로 세 스 가 accept 와 read 사건 을 처리 하 는 리 셋 함수 입 니 다.지난 장 놀 라 움 처리 에서 ngx 에 중점 을 두 었 습 니 다.event_process_posted 라 는 방법.
4. ngx_event_pipe. c: 주로 파 이 프 를 처리 하 는 데 사 용 됩 니 다.
5. ngx_event_openssl. c: 주로 SSL 채널 을 처리 하 는 데 사 용 됩 니 다.HTTPS 프로 토 콜.
6. ngx_event_connect. c: 주로 TCP 의 연결 채널 을 처리 하 는 데 사 용 됩 니 다.
7. ngx_event_accept. c: 핵심 은 ngxevent_accept 와 ngxevent_recvmsg, accept 와 read 이 벤트 를 처리 하 는 리 셋 함수 handler 입 니 다.
8. modules / xxxx. c: 주로 각종 플랫폼 의 이벤트 모델 을 밀봉 했다.우리 쪽 은 주로 ngxepoll_module. c 모듈.
중요 데이터 구조
아래 의 몇 가지 데이터 구 조 는 이벤트 모듈 에서 매우 흔히 볼 수 있 으 므 로 반드시 매우 익숙해 야 한다.
ngx_listening_s: 주로 수사 구조 로 socket 의 정 보 를 저장 합 니 다.
ngx_connection_s: 연결 에 관 한 정보 와 읽 기와 쓰기 이 벤트 를 저장 합 니 다.
ngx_event_s: 주로 이벤트 의 데이터 구 조 를 저장 합 니 다.
ngx_listening_수사 구조
주로 연 결 된 socket 을 저장 하 는 수사 구조 입 니 다.
/**
 * socket    
 */
struct ngx_listening_s {
    ngx_socket_t        fd;	/*      , socket */

    struct sockaddr    *sockaddr;	/* socket   */
    socklen_t           socklen;    /* size of sockaddr */
    size_t              addr_text_max_len;
    ngx_str_t           addr_text;

    int                 type;

    int                 backlog;/*    */
    int                 rcvbuf;	/*     buffer */
    int                 sndbuf;	/*      buffer */
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
    int                 keepidle;
    int                 keepintvl;
    int                 keepcnt;
#endif

    /* handler of accepted connection */
    ngx_connection_handler_pt   handler; /*            */

    void               *servers;  /* array of ngx_http_in_addr_t, for example */

    ngx_log_t           log;
    ngx_log_t          *logp;

    size_t              pool_size;
    /* should be here because of the AcceptEx() preread */
    size_t              post_accept_buffer_size;
    /* should be here because of the deferred accept */
    ngx_msec_t          post_accept_timeout;

    ngx_listening_t    *previous; /*    ngx_listening_t */
    ngx_connection_t   *connection; /*      */

    ngx_uint_t          worker;

    unsigned            open:1; /*  1        , 0       */
    unsigned            remain:1;/*  1              , 0              */
    unsigned            ignore:1; /*  1        ngx_listening_t        , 0          */

    unsigned            bound:1;       /* already bound */
    unsigned            inherited:1;   /* inherited from previous process */
    unsigned            nonblocking_accept:1;
    unsigned            listen:1; /*  1                  */
    unsigned            nonblocking:1;
    unsigned            shared:1;    /* shared between threads or processes */
    unsigned            addr_ntop:1;
    unsigned            wildcard:1;

#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
    unsigned            ipv6only:1;
#endif
#if (NGX_HAVE_REUSEPORT)
    unsigned            reuseport:1;
    unsigned            add_reuseport:1;
#endif
    unsigned            keepalive:2;

#if (NGX_HAVE_DEFERRED_ACCEPT)
    unsigned            deferred_accept:1;
    unsigned            delete_deferred:1;
    unsigned            add_deferred:1;
#ifdef SO_ACCEPTFILTER
    char               *accept_filter;
#endif
#endif
#if (NGX_HAVE_SETFIB)
    int                 setfib;
#endif

#if (NGX_HAVE_TCP_FASTOPEN)
    int                 fastopen;
#endif

};

ngx_connection_s socket 연결 대상 구조
연결 에 관 한 정보 와 읽 기와 쓰기 이 벤트 를 저장 합 니 다.
struct ngx_connection_s {

	/*       ngx_connection_s */
    void               *data;

    /*        */
    ngx_event_t        *read;

    /*     */
    ngx_event_t        *write;

    /* socket   */
    ngx_socket_t        fd;

    /*           */
    ngx_recv_pt         recv;

    /*           */
    ngx_send_pt         send;

    /*             */
    ngx_recv_chain_pt   recv_chain;

    /*             */
    ngx_send_chain_pt   send_chain;

    /*              */
    ngx_listening_t    *listening;

    off_t               sent;

    /*    */
    ngx_log_t          *log;

    /*     */
    ngx_pool_t         *pool;

    int                 type;

    /* socket      */
    struct sockaddr    *sockaddr;
    socklen_t           socklen;
    ngx_str_t           addr_text;

    ngx_str_t           proxy_protocol_addr;
    in_port_t           proxy_protocol_port;

#if (NGX_SSL)
    ngx_ssl_connection_t  *ssl;
#endif

    /*     socket      */
    struct sockaddr    *local_sockaddr;
    socklen_t           local_socklen;

    /*                  */
    ngx_buf_t          *buffer;

    /*                    cycle        cycle->free_connections*/
    ngx_queue_t         queue;

    /*              ,number+1   */
    ngx_atomic_uint_t   number;

    /*          */
    ngx_uint_t          requests;

    unsigned            buffered:8;

    /*        */
    unsigned            log_error:3;     /* ngx_connection_log_error_e */
    /*           */
    unsigned            timedout:1;
    /*             */
    unsigned            error:1;
    /*          ,   ,          */
    unsigned            destroyed:1;

    /*           */
    unsigned            idle:1;
    /*         */
    unsigned            reusable:1;
    /*      */
    unsigned            close:1;
    unsigned            shared:1;

    /*                */
    unsigned            sendfile:1;
    unsigned            sndlowat:1;
    /*   tcp nodely    */
    unsigned            tcp_nodelay:2;   /* ngx_connection_tcp_nodelay_e */
    /*   tcp nopush     */
    unsigned            tcp_nopush:2;    /* ngx_connection_tcp_nopush_e */

    unsigned            need_last_buf:1;

#if (NGX_HAVE_IOCP)
    unsigned            accept_context_updated:1;
#endif

#if (NGX_HAVE_AIO_SENDFILE)
    unsigned            busy_count:2;
#endif

#if (NGX_THREADS)
    ngx_thread_task_t  *sendfile_task;
#endif
};

ngx_event_s 이벤트 데이터 구조
struct ngx_event_s {

	/*       ,   data  ngx_connection_t    . (    IO     ngx_event_aio_t   ) */
    void            *data;

    unsigned         write:1;

    /*            */
    unsigned         accept:1;

    /* used to detect the stale events in kqueue and epoll */
    unsigned         instance:1;

    /*
     * the event was passed or would be passed to a kernel;
     * in aio mode - operation was posted.
     */
    /*           */
    unsigned         active:1;

    unsigned         disabled:1;

    /* the ready event; in aio mode 0 means that no operation can be posted */
    unsigned         ready:1;

    unsigned         oneshot:1;

    /* aio operation is complete */
    unsigned         complete:1;

    unsigned         eof:1;
    unsigned         error:1;

    unsigned         timedout:1;
    unsigned         timer_set:1;

    unsigned         delayed:1;

    unsigned         deferred_accept:1;

    /* the pending eof reported by kqueue, epoll or in aio chain operation */
    unsigned         pending_eof:1;

    unsigned         posted:1;

    unsigned         closed:1;

    /* to test on worker exit */
    unsigned         channel:1;
    unsigned         resolver:1;

    unsigned         cancelable:1;

#if (NGX_WIN32)
    /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
    unsigned         accept_context_updated:1;
#endif

#if (NGX_HAVE_KQUEUE)
    unsigned         kq_vnode:1;

    /* the pending errno reported by kqueue */
    int              kq_errno;
#endif

    /*
     * kqueue only:
     *   accept:     number of sockets that wait to be accepted
     *   read:       bytes to read when event is ready
     *               or lowat when event is set with NGX_LOWAT_EVENT flag
     *   write:      available space in buffer when event is ready
     *               or lowat when event is set with NGX_LOWAT_EVENT flag
     *
     * epoll with EPOLLRDHUP:
     *   accept:     1 if accept many, 0 otherwise
     *   read:       1 if there can be data to read, 0 otherwise
     *
     * iocp: TODO
     *
     * otherwise:
     *   accept:     1 if accept many, 0 otherwise
     */

#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
    int              available;
#else
    unsigned         available:1;
#endif

    ngx_event_handler_pt  handler;


#if (NGX_HAVE_IOCP)
    ngx_event_ovlp_t ovlp;
#endif

    ngx_uint_t       index;

    ngx_log_t       *log;

    ngx_rbtree_node_t   timer;

    /* the posted queue */
    ngx_queue_t      queue;

#if 0

    /* the threads support */

    /*
     * the event thread context, we store it here
     * if $(CC) does not understand __thread declaration
     * and pthread_getspecific() is too costly
     */

    void            *thr_ctx;

#if (NGX_EVENT_T_PADDING)

    /* event should not cross cache line in SMP */

    uint32_t         padding[NGX_EVENT_T_PADDING];
#endif
#endif
};

좋은 웹페이지 즐겨찾기