Nginx源代码分析之初始化(二)

入口函数main位于 src/core/nginx.c

对于单进程方式

调用ngx_single_process_cycle来初始化进程及socket模型

对于多线程模式,调用ngx_master_process_cycle初始化主线程


先看看单线程模型:

ngx_single_process_cycle位于src/os/win32/ngx_process_cycle.c


主要代码在工作线程ngx_worker_thread里面,如下:

static ngx_thread_value_t __stdcall
ngx_worker_thread(void *data)
{
    ngx_int_t          n;
    ngx_uint_t         i;
    ngx_cycle_t       *cycle;
    ngx_connection_t  *c;


    cycle = (ngx_cycle_t *) ngx_cycle;


    for (n = 0; ngx_modules[n]; n++) {
        if (ngx_modules[n]->init_process) {
            if (ngx_modules[n]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }


    while (!ngx_quit) {


        if (ngx_exiting) {


            c = cycle->connections;


            for (i = 0; i < cycle->connection_n; i++) {


                /* THREAD: lock */


                if (c[i].fd != (ngx_socket_t) -1 && c[i].idle) {
                    c[i].close = 1;
                    c[i].read->handler(c[i].read);
                }
            }


            ngx_event_cancel_timers();


            if (ngx_event_timer_rbtree.root
                == ngx_event_timer_rbtree.sentinel)
            {
                break;
            }
        }


        ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle");


        ngx_process_events_and_timers(cycle);


        if (ngx_terminate) {
            return 0;
        }


        if (ngx_quit) {
            ngx_quit = 0;


            if (!ngx_exiting) {
                ngx_close_listening_sockets(cycle);
                ngx_exiting = 1;
            }
        }


        if (ngx_reopen) {
            ngx_reopen = 0;
            ngx_reopen_files(cycle, -1);
        }
    }


    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");


    return 0;
}

其中关键是调用init_process,init_process是struct ngx_module_s里面的一个成员。
ngx_module_s定义如下:
struct ngx_module_s {
    ngx_uint_t            ctx_index;
    ngx_uint_t            index;


    ngx_uint_t            spare0;
    ngx_uint_t            spare1;
    ngx_uint_t            spare2;
    ngx_uint_t            spare3;
    ngx_uint_t            version;
    void                 *ctx;
    ngx_command_t        *commands;
    ngx_uint_t            type;
    ngx_int_t           (*init_master)(ngx_log_t *log);
    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);
    void                (*exit_thread)(ngx_cycle_t *cycle);
    void                (*exit_process)(ngx_cycle_t *cycle);
    void                (*exit_master)(ngx_cycle_t *cycle);
    uintptr_t             spare_hook0;
    uintptr_t             spare_hook1;
    uintptr_t             spare_hook2;
    uintptr_t             spare_hook3;
    uintptr_t             spare_hook4;
    uintptr_t             spare_hook5;
    uintptr_t             spare_hook6;
    uintptr_t             spare_hook7;
};

init_process作为指针指向的实际上是函数static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);该函数位于 src/event/ngx_event.c。

疑点在于ngx_event_process_init何时初始化给init_process,答案是在ngx_event.c中声明了一个全局变量:

ngx_module_t  ngx_event_core_module = {
    NGX_MODULE_V1,
    &ngx_event_core_module_ctx,            /* module context */
    ngx_event_core_commands,               /* module directives */
    NGX_EVENT_MODULE,                      /* module type */
    NULL,                                  /* init master */
    ngx_event_module_init,                 /* init module */
    ngx_event_process_init,                /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};


这里对socket模型进行初始化
   if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
            /* fatal */
            exit(2);

        }


init也是一个函数指针,实际调用的是static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer),它位于src/event/modules/ngx_iocp_module.c里面。
详细代码如下
static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{
    ngx_iocp_conf_t  *cf;


    cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);

    if (iocp == NULL) {
        iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
                                      cf->threads);
    }

    if (iocp == NULL) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "CreateIoCompletionPort() failed");
        return NGX_ERROR;
    }
    ngx_io = ngx_iocp_io;
    ngx_event_actions = ngx_iocp_module_ctx.actions;
    ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT;

    if (timer == 0) {
        return NGX_OK;
    }
    /*
     * The waitable timer could not be used, because
     * GetQueuedCompletionStatus() does not set a thread to alertable state
     */

    if (timer_thread == NULL) {

        msec = timer;

        if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log)
            != 0)
        {
            return NGX_ERROR;
        }
    }

    ngx_event_flags |= NGX_USE_TIMER_EVENT;
    return NGX_OK;
}

init的初始化也是通过声明全局结构体的方式,在ngx_iocp_module.c里面,如下

ngx_event_module_t  ngx_iocp_module_ctx = {
    &iocp_name,
    ngx_iocp_create_conf,                  /* create configuration */
    ngx_iocp_init_conf,                    /* init configuration */


    {
        ngx_iocp_add_event,                /* add an event */
        NULL,                              /* delete an event */
        NULL,                              /* enable an event */
        NULL,                              /* disable an event */
        NULL,                              /* add an connection */
        ngx_iocp_del_connection,           /* delete an connection */
        NULL,                              /* process the changes */
        ngx_iocp_process_events,           /* process the events */
        ngx_iocp_init,                     /* init the events */
        ngx_iocp_done                      /* done the events */
    }


};

这里面初始化的其他处理函数在后面会用到。

首先调用CreateIoCompletionPort创建IOCP对象,然后调用ngx_create_thread创建多个线程,并纳入到IOCP的线程池中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值