欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

nginx中void****ctx如何初始化

程序员文章站 2022-07-02 08:37:22
...

nginx的一切都是通过ngx_cycle_s来展开的,按看一下其第一个参数:

struct ngx_cycle_s {
    void                  ****conf_ctx;
    ngx_pool_t               *pool;
    ...
    }

注意conf_ctx有四个指针,就是数组的数组,那么它是怎么初始化的呢?
我们在这里先列出几个核心模块:

//第一个核心模块为ngx_core_module,在nginx.c中
static ngx_command_t  ngx_core_commands[] = {

    { ngx_string("daemon"),
      NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      0,
      offsetof(ngx_core_conf_t, daemon),
      NULL },

    { ngx_string("master_process"),
      NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      0,
      offsetof(ngx_core_conf_t, master),
      NULL },
      ....
      }
static ngx_core_module_t  ngx_core_module_ctx = {
    ngx_string("core"),
    ngx_core_module_create_conf,
    ngx_core_module_init_conf
};


ngx_module_t  ngx_core_module = {
    NGX_MODULE_V1,
    &ngx_core_module_ctx,                  /* module context */
    ngx_core_commands,                     /* module directives */
    NGX_CORE_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
};

//第二个模块是conf模块,只有一个,比较特殊
static ngx_command_t  ngx_conf_commands[] = {

    { ngx_string("include"),
      NGX_ANY_CONF|NGX_CONF_TAKE1,
      ngx_conf_include,
      0,
      0,
      NULL },

      ngx_null_command
};


ngx_module_t  ngx_conf_module = {
    NGX_MODULE_V1,
    NULL,                                  /* module context */
    ngx_conf_commands,                     /* module directives */
    NGX_CONF_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    ngx_conf_flush_files,                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};


/* The eight fixed arguments */

static ngx_uint_t argument_number[] = {
    NGX_CONF_NOARGS,
    NGX_CONF_TAKE1,
    NGX_CONF_TAKE2,
    NGX_CONF_TAKE3,
    NGX_CONF_TAKE4,
    NGX_CONF_TAKE5,
    NGX_CONF_TAKE6,
    NGX_CONF_TAKE7
};

//第三个核心模块为ngx_events_module,在ngx_event.c中
static ngx_command_t  ngx_events_commands[] = {

    { ngx_string("events"),
      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
      ngx_events_block,
      0,
      0,
      NULL },

      ngx_null_command
};


static ngx_core_module_t  ngx_events_module_ctx = {
    ngx_string("events"),
    NULL,
    ngx_event_init_conf
};


ngx_module_t  ngx_events_module = {
    NGX_MODULE_V1,
    &ngx_events_module_ctx,                /* module context */
    ngx_events_commands,                   /* module directives */
    NGX_CORE_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
};
//第四个核心模块是ngx_http_module,在ngx_http.c中
ngx_uint_t   ngx_http_max_module;


ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
ngx_http_output_body_filter_pt    ngx_http_top_body_filter;
ngx_http_request_body_filter_pt   ngx_http_top_request_body_filter;
static ngx_command_t  ngx_http_commands[] = {

    { ngx_string("http"),
      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
      ngx_http_block,
      0,
      0,
      NULL },

      ngx_null_command
};


static ngx_core_module_t  ngx_http_module_ctx = {
    ngx_string("http"),
    NULL,
    NULL
};


ngx_module_t  ngx_http_module = {
    NGX_MODULE_V1,
    &ngx_http_module_ctx,                  /* module context */
    ngx_http_commands,                     /* module directives */
    NGX_CORE_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
};
//第五个核心模块是ngx_rtmp_module
ngx_uint_t  ngx_rtmp_max_module;
static ngx_command_t  ngx_rtmp_commands[] = {

    { ngx_string("rtmp"),
      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
      ngx_rtmp_block,
      0,
      0,
      NULL },

      ngx_null_command
};


static ngx_core_module_t  ngx_rtmp_module_ctx = {
    ngx_string("rtmp"),
    NULL,
    NULL
};


ngx_module_t  ngx_rtmp_module = {
    NGX_MODULE_V1,
    &ngx_rtmp_module_ctx,                  /* module context */
    ngx_rtmp_commands,                     /* module directives */
    NGX_CORE_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    ngx_rtmp_init_process,                 /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

以上就是我们本次关心的几个核心模块

下面再ngx_cycle.c的main中:

 main-->ngx_init_cycle(){
 ...
 //在这里分配空间,ngx_max_module就是ngx_module_t *ngx_modules[] + 128,
 //ngx_modules[]有config生成:
 //ngx_module_t *ngx_modules[] = {
//    &ngx_core_module,
//    &ngx_errlog_module,
//    &ngx_conf_module,
//    &ngx_rtmp_module,
//    &ngx_rtmp_core_module,
//    ‘’‘’
//    &ngx_openssl_module,
//    &ngx_regex_module, //通配符
//    &ngx_events_module,
//    &ngx_event_core_module,
//    &ngx_epoll_module,
//    &ngx_http_module,
//    &ngx_http_core_module,
//    ‘’‘’‘
//   
// }
 
   cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    if (cycle->conf_ctx == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

...

//在这里调用核心模块的create_conf函数,通过上面可以知道,只有ngx_core_module才有create_conf
//其余核心模块没有,那么其余模块是在什么时候create_conf呢?
//其实其余的都是在 ngx_xxxx_block,中开始创建的
    for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = cycle->modules[i]->ctx;

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
    }
    ’‘’‘’‘
//在这个for循环中进行NGX_CORE_MODULE初始化
for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = cycle->modules[i]->ctx;

        if (module->init_conf) {
            if (module->init_conf(cycle,
                                  cycle->conf_ctx[cycle->modules[i]->index])
                == NGX_CONF_ERROR)
            {
                environ = senv;
                ngx_destroy_cycle_pools(&conf);
                return NULL;
            }
        }
    }

’‘’‘
//注意这个conf是做什么用的?
//struct ngx_conf_s {
//    char                 *name;
//    ngx_array_t          *args;
//
//    ngx_cycle_t          *cycle;
//    ngx_pool_t           *pool;
//    ngx_pool_t           *temp_pool;
//    ngx_conf_file_t      *conf_file;
//    ngx_log_t            *log;
//
//    void                 *ctx;
//    ngx_uint_t            module_type;
//    ngx_uint_t            cmd_type;

//    ngx_conf_handler_pt   handler;
//    void                 *handler_conf;
//};
  ngx_memzero(&conf, sizeof(ngx_conf_t));
    /* STUB: init array ? */
    conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
    if (conf.args == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
    if (conf.temp_pool == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }


    conf.ctx = cycle->conf_ctx;
    conf.cycle = cycle;
    conf.pool = pool;
    conf.log = log;
    conf.module_type = NGX_CORE_MODULE;
    conf.cmd_type = NGX_MAIN_CONF;
    
    if (ngx_conf_param(&conf) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }
//这里就是开始解析配置文件了,注意传入的conf
//ngx_conf_parse---->
//  for(;;){
//       rc = ngx_conf_read_token(cf);
//       //核心就在这里
//		 rc = ngx_conf_handler(cf, rc);
//}
//ngx_conf_handler核心for循环{}如下:
//遍历所有commands
// name = cf->args->elts;这个name就是解析到的nginx.conf
//关于nginx.conf可以参考:
//for (i = 0; cf->cycle->modules[i]; i++) {
//        cmd = cf->cycle->modules[i]->commands;
//        if (cmd == NULL) {
//            continue;
//        }

//        for ( /* void */ ; cmd->name.len; cmd++) {//简单len比较
//            if (name->len != cmd->name.len) {
//                continue;
//            }

//            if (ngx_strcmp(name->data, cmd->name.data) != 0) {//len相等再对str比较
//                continue;
//            }
//            found = 1;//说明字符串跟command中的相同

//            //如果模块类型不符返回
//            if (cf->cycle->modules[i]->type != NGX_CONF_MODULE
//                && cf->cycle->modules[i]->type != cf->module_type)
//            {
//                continue;
//            }

‘‘’
// cmd就是执行核心模块的command中的set,因为在配置文件中只有核心模块的名字
// http 、rtmp 、events 才出现在配置文件中,更加确切的说,这里执行的是核心模块
// 的		ngx_xxxx_block,继续创建NGX_EVENT_MODULE、
//struct ngx_command_s {
//    ngx_str_t             name;
//    ngx_uint_t            type;
//    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
//    ngx_uint_t            conf;
//    ngx_uint_t            offset;
//    void                 *post;
};
//            rv = cmd->set(cf, cmd, conf);//关键在这里

//            if (rv == NGX_CONF_OK) {
//                return NGX_OK;
//            }

//            if (rv == NGX_CONF_ERROR) {
//                return NGX_ERROR;
//            }

//            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "\"%s\" directive %s", name->data, rv);

//            return NGX_ERROR;
//        }
//    }

   if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }
}
相关标签: 音视频资料