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,
};
- name: 命令的名称,nginx字符串
- type: 命令的类型,指定指令作用的类型以及所带参数的数量
- set: 执行该命令的函数指针
- conf: 配置信息
- offset: 偏移量
- 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 // 最后以一个空指令结尾, 这个在源码中很常见的一种方式
};
offsetof系统宏:
前面见到这个宏,并简单的介绍了它的含义, 下面详细介绍下这个系统宏。
宏定义: #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;
以上结构体就是顶层配置指令的列表。这些指令在nginx.conf文件中都可以看到:
有了上面的基础介绍, 就很清楚的指导ngx_core_commands这个变量是为了设置顶层指令的一些基本信息及执行方法名称。
后面再介绍这些方法是如何调用的。