nginx-rtmp-module 执行流程
统计模块数量
nginx.c中main()函数
ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; }
上述代码在nginx.c的main函数中,其作用为:
- 统计系统中到底有多少个模块,记录在全局变量ngx_max_module中。
- 将每个模块在ngx_modules数组中的序号,记录在模块的index变量中。
在ngx_init_cycle函数执行每个模块ngx_modules[i]->ctx中的create_conf函数
for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->create_conf) { rv = module->create_conf(cycle); if (rv == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->conf_ctx[ngx_modules[i]->index] = rv; } }
以上代码对所有的ngx_core_module_t类型的模块,调用其ctx成员中的create_conf函数。
在ngx_init_cycle函数执行ngx_conf_param(&conf)和ngx_conf_parse(&conf, &cycle->conf_file)
ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)调用函数ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)。
在函数ngx_conf_handler中调用ngx_command_t 中的set()函数,即cmd->set(cf, cmd, conf);
对于模块ngx_rtmp_module,set函数对应ngx_rtmp_block
函数ngx_rtmp_block统计NGX_RTMP_MODULE数量
ngx_rtmp_max_module = 0; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_RTMP_MODULE) { continue; } ngx_modules[m]->ctx_index = ngx_rtmp_max_module++; }
上面的代码主要做了两件事情:
- 遍历所有的ngx_rtmp_module_t类型的模块,统计这种模块的个数,存在变量ngx_rtmp_max_module中。
- 初始化每个ngx_rtmp_module_t类型的模块的ctx_index变量,该值的涵义是每个ngx_rtmp_module_t模块在所有该类模块中的序号。
函数ngx_rtmp_block调用ngx_rtmp_module_t create_main_conf、create_srv_conf和create_loc_conf函数
for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; if (module->create_main_conf) { ctx->main_conf[mi] = module->create_main_conf(cf); if (ctx->main_conf[mi] == NULL) { return NGX_CONF_ERROR; } } if (module->create_srv_conf) { ctx->srv_conf[mi] = module->create_srv_conf(cf); if (ctx->srv_conf[mi] == NULL) { return NGX_CONF_ERROR; } } if (module->create_app_conf) { ctx->app_conf[mi] = module->create_app_conf(cf); if (ctx->app_conf[mi] == NULL) { return NGX_CONF_ERROR; } }
ngx_rtmp_conf_ctx_t中的指针数组main_conf,srv_conf和app_conf被赋值。
函数ngx_rtmp_block调用ngx_rtmp_module_t preconfiguration函数
for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->preconfiguration) { if (module->preconfiguration(cf) != NGX_OK) { return NGX_CONF_ERROR; } } }
函数ngx_rtmp_block解析rtmp配置
/* parse inside the rtmp{} block */ cf->module_type = NGX_RTMP_MODULE; cf->cmd_type = NGX_RTMP_MAIN_CONF; rv = ngx_conf_parse(cf, NULL); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; }
函数ngx_rtmp_block调用ngx_rtmp_module_t init_main_conf,merge_srv_conf和merge_app_conf函数
/* init rtmp{} main_conf's, merge the server{}s' srv_conf's */ cmcf = ctx->main_conf[ngx_rtmp_core_module.ctx_index]; cscfp = cmcf->servers.elts; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; /* init rtmp{} main_conf's */ cf->ctx = ctx; if (module->init_main_conf) { rv = module->init_main_conf(cf, ctx->main_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } for (s = 0; s < cmcf->servers.nelts; s++) { /* merge the server{}s' srv_conf's */ cf->ctx = cscfp[s]->ctx; if (module->merge_srv_conf) { rv = module->merge_srv_conf(cf, ctx->srv_conf[mi], cscfp[s]->ctx->srv_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } if (module->merge_app_conf) { /* merge the server{}'s app_conf */ /*ctx->app_conf = cscfp[s]->ctx->loc_conf;*/ rv = module->merge_app_conf(cf, ctx->app_conf[mi], cscfp[s]->ctx->app_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } /* merge the applications{}' app_conf's */ cscf = cscfp[s]->ctx->srv_conf[ngx_rtmp_core_module.ctx_index]; rv = ngx_rtmp_merge_applications(cf, &cscf->applications, cscfp[s]->ctx->app_conf, module, mi); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } } }
函数ngx_rtmp_block调用ngx_rtmp_module_t postconfiguration函数
for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->postconfiguration) { if (module->postconfiguration(cf) != NGX_OK) { return NGX_CONF_ERROR; } } }
在ngx_init_cycle函数执行每个模块ngx_modules[i]->ctx中的init_conf函数
for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->init_conf) { if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) == NGX_CONF_ERROR) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } } }
以上代码对所有的ngx_core_module_t类型的模块,调用其ctx成员的init_conf钩子函数。
在ngx_init_cycle函数执行每个模块ngx_modules[i]中的init_module函数
for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_module) { if (ngx_modules[i]->init_module(cycle) != NGX_OK) { /* fatal */ exit(1); } } }
注释1 ngx_module_t:
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;};
注释2 ngx_core_module_t:
typedef struct { ngx_str_t name; void *(*create_conf)(ngx_cycle_t *cycle); char *(*init_conf)(ngx_cycle_t *cycle, void *conf);} ngx_core_module_t;
注释3 ngx_rtmp_module_t:
typedef struct { ngx_int_t (*preconfiguration)(ngx_conf_t *cf); ngx_int_t (*postconfiguration)(ngx_conf_t *cf); void *(*create_main_conf)(ngx_conf_t *cf); char *(*init_main_conf)(ngx_conf_t *cf, void *conf); void *(*create_srv_conf)(ngx_conf_t *cf); char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); void *(*create_app_conf)(ngx_conf_t *cf); char *(*merge_app_conf)(ngx_conf_t *cf, void *prev, void *conf);} ngx_rtmp_module_t;