ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

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

2021-06-19 19:57:38  阅读:176  来源: 互联网

标签:CONF NGX void ctx module nginx conf NULL ngx


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

标签:CONF,NGX,void,ctx,module,nginx,conf,NULL,ngx
来源: https://blog.csdn.net/weixin_43360707/article/details/118057698

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有