nginx源码分析之ngx_core_commands

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这个变量是为了设置顶层指令的一些基本信息及执行方法名称。

后面再介绍这些方法是如何调用的。


你可能感兴趣的:(nginx源码分析之ngx_core_commands)