ngx_core_commands是核心模块指令, 该变量的定义是在src/core/nginx.c中定义的。该变量为一个数组, 每个元素都是ngx_command_t类型,下面逐步解析这个变量。
ngx_command_t类型:(src/core/ngx_conf_file.h)
typedef ngx_command_s ngx_command_t; 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; //这个变量基本上都是NULL, };
ngx_core_commands变量:
static ngx_command_t ngx_core_commands[] = { { ngx_string("daemon"), // 守护进程指令 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, // 指令类型为顶层指令,直接存储型的指令, MAIN,DIRECT一般都一起出现 ngx_conf_set_flag_slot, // 执行该命令的方法 0, // 配置信息 offsetof(ngx_core_conf_t, daemon), // 偏移量, 这个使用了offsetof这个系统宏获取deamon在结构体ngx_core_conf_t中的偏移量,后面单独胡介绍 NULL }, // 最后一个为NULL, post { 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 }, { ngx_string("timer_resolution"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, 0, offsetof(ngx_core_conf_t, timer_resolution), NULL }, { ngx_string("pid"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, pid), NULL }, { ngx_string("lock_file"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, lock_file), NULL }, { ngx_string("worker_processes"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_worker_processes, 0, 0, NULL }, { ngx_string("debug_points"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_enum_slot, 0, offsetof(ngx_core_conf_t, debug_points), &ngx_debug_points }, //注意这里使用了&ngx_debug_points { ngx_string("user"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12, ngx_set_user, 0, 0, NULL }, { ngx_string("worker_priority"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_priority, 0, 0, NULL }, { ngx_string("worker_cpu_affinity"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE, ngx_set_cpu_affinity, 0, 0, NULL }, { ngx_string("worker_rlimit_nofile"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, rlimit_nofile), NULL }, { ngx_string("worker_rlimit_core"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_off_slot, 0, offsetof(ngx_core_conf_t, rlimit_core), NULL }, { ngx_string("worker_rlimit_sigpending"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, rlimit_sigpending), NULL }, { ngx_string("working_directory"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, working_directory), NULL }, { ngx_string("env"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_env, 0, 0, NULL }, #if (NGX_THREADS) { ngx_string("worker_threads"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, worker_threads), NULL }, { ngx_string("thread_stack_size"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, 0, offsetof(ngx_core_conf_t, thread_stack_size), NULL }, #endif ngx_null_command // 最后以一个空指令结尾, 这个在源码中很常见的一种方式 };
前面见到这个宏,并简单的介绍了它的含义, 下面详细介绍下这个系统宏。
宏定义: #define offsetof(s,m) (size_t)&(((s *)0)->m)
s:为结构体, m为结构体中的元素。
(s *)0将0强制转换为s类型的指针变量, 那么这个指针的地址就是0.
( (s *)0)->m就是m的位置, 然后对这个位置取地址,就是m相对于结构体s的偏移量。
理解了上面的系统宏offsetof的实现原理, 下面我们看看ngx_core_commands中用到的ngx_core_conf_t结构体。
ngx_core_conf_t结构体:
typedef struct { ngx_flag_t daemon; ngx_flag_t master; ngx_msec_t timer_resolution; ngx_int_t worker_processes; ngx_int_t debug_points; ngx_int_t rlimit_nofile; ngx_int_t rlimit_sigpending; off_t rlimit_core; int priority; ngx_uint_t cpu_affinity_n; uint64_t *cpu_affinity; char *username; ngx_uid_t user; ngx_gid_t group; ngx_str_t working_directory; ngx_str_t lock_file; ngx_str_t pid; ngx_str_t oldpid; ngx_array_t env; char **environment; #if (NGX_THREADS) ngx_int_t worker_threads; size_t thread_stack_size; #endif } ngx_core_conf_t; typedef struct { ngx_pool_t *pool; /* pcre's malloc() pool */ } ngx_core_tls_t;
有了上面的基础介绍, 就很清楚的指导ngx_core_commands这个变量是为了设置顶层指令的一些基本信息及执行方法名称。
后面再介绍这些方法是如何调用的。