您的位置:首页 > 理论基础 > 数据结构算法

nginx源码初读(11)--让烦恼从数据结构开始(ngx_command/ngx_module/ngx_conf)

2016-03-10 15:24 846 查看
第一点:ngx_command_t

ngx_core_commands是nginx中的核心模块指令, 它的类型就是ngx_command_t。在每一个module的结构体中,也都有一个ngx_command_t。

typedef struct 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);
/*  当nginx在解析配置的时候,如果遇到这个配置指令,将会把读取到的值传递给这个函数进行解析保存。
因为具体每个配置指令的值如何处理,只有定义这个配置指令的人是最清楚的,set可能复杂也可能很简单。
比如errlog模块的“error_log”指令就是调用ngx_error_log写一条日志,并不需要存储什么配置数据。
*  cf: 保存从配置文件读取到的原始字符串以及相关信息。这个参数的args字段是一个ngx_str_t类型的数组,
该数组首元素是这个配置指令本身,第二个元素开始才是参数。
cmd: 这个配置指令对应的ngx_command_t结构。
conf: 就是定义的存储这个配置值的结构体
*/

ngx_uint_t            conf;
/* 该字段被NGX_HTTP_MODULE类型模块所用,指定当前配置项存储的内存位置。实际上是使用哪个内存池的问题。
因为http模块对所有http模块所要保存的配置信息,划分了main, server和location三个地方进行存储,
每个地方都有一个内存池用来分配存储这些信息的内存。
这里可能的值为NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET或NGX_HTTP_LOC_CONF_OFFSET。
当然也可以直接置为0,就是NGX_HTTP_MAIN_CONF_OFFSET。
*/

ngx_uint_t            offset;
/* 指定该配置项值的精确存放位置,一般指定为某一个结构体变量的字段偏移。
比如我们定义了一个结构体A,该项配置的值需要存储到该结构体的b字段。那么在这里就可以填写offsetof(A, b)。
对于有些配置项,它的值不需要保存或者是需要保存到更为复杂的结构中时,这里可以设置为0。
*/

void                 *post;
/* 可指向任何一个在读取配置过程中需要的数据,以便于进行配置读取的处理。大多时候不需要,设为0即可。*/
};

static ngx_command_t  ngx_core_commands[];   // 保存了核心指令


第二点:ngx_module_t

对于开发一个模块来说,我们都需要定义一个ngx_module_t类型的变量来说明这个模块本身的信息,从某种意义上来说,这是这个模块最重要的一个信息。它告诉了nginx这个模块的一些信息,上面定义的配置信息,还有模块上下文信息,都是通过这个结构来告诉nginx系统的,也就是加载模块的上层代码,都需要通过定义的这个结构,来获取这些信息。

typedef struct ngx_module_s      ngx_module_t;
struct ngx_module_s {
ngx_uint_t            ctx_index;
/* 在相应模块类的计数,nginx模块分为四种:core、event、http和mail
* ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
*/

ngx_uint_t            index;
/* 模块计数器,按照每个模块在ngx_modules[]数组中的声明顺序,从0开始依次给每个模块赋值 */

ngx_uint_t            spare0;
ngx_uint_t            spare1;
ngx_uint_t            spare2;
ngx_uint_t            spare3;

ngx_uint_t            version;
/* 模块当前版本 */

void                 *ctx;
/* 模块上下文,不同类别模块有不同上下文,ngx_http_conf_ctx_t/ngx_mail_conf_ctx_t/... */

ngx_command_t        *commands;
/* 该模块的命令集,是ngx_command_t数组 */

ngx_uint_t            type;
/* 模块种类:core、event、http和mail */

ngx_int_t           (*init_master)(ngx_log_t *log);           // master进程初始化调用
ngx_int_t           (*init_module)(ngx_cycle_t *cycle);       // 模块初始化调用
ngx_int_t           (*init_process)(ngx_cycle_t *cycle);      // worker进程初始化调用
ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);       // 线程初始化调用
void                (*exit_thread)(ngx_cycle_t *cycle);       // 线程退出调用
void                (*exit_process)(ngx_cycle_t *cycle);      // worker进程结束调用
void                (*exit_master)(ngx_cycle_t *cycle);       // master进程结束调用
/* callback:如果该模块需要发生这些行为执行特定的功能,可以通过这些回调函数指针注册一个回调函数接口来实现 */

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

#define NGX_NUMBER_MAJOR  3
#define NGX_NUMBER_MINOR  1

#define NGX_MODULE_V1          0, 0, 0, 0,                              \
NGX_DSO_ABI_COMPATIBILITY, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR
/* 前7个成员初始化 */

#define NGX_MODULE_V1_PADDING  0, 0, 0, 0, 0, 0, 0, 0
/* 后8个成员初始化 */


第三点:ngx_conf_t

该结构体用于Nginx在解析配置文件时描述每个指令的属性,是Nginx程序中非常重要的一个数据结构。

typedef struct {
ngx_file_t            file;            // 文件
ngx_buf_t            *buffer;          // 文件内容
ngx_uint_t            line;            // 文件行数
} ngx_conf_file_t;

typedef char
a8e0
*(*ngx_conf_handler_pt)(ngx_conf_t *cf,
ngx_command_t *dummy, void *conf);

typedef struct ngx_conf_s   ngx_conf_t
struct ngx_conf_s {
char                 *name;            // 存放当前解析到的指令

ngx_array_t          *args;            // 从配置中读取指令的名称和相对应的参数

ngx_cycle_t          *cycle;           // 对应的cycle(一个进程有一个cycle)
ngx_pool_t           *pool;            // 对应的内存池
ngx_pool_t           *temp_pool;       // 临时内存池,在解析配置文件的时候使用,之后释放了
ngx_conf_file_t      *conf_file;       // 配置文件的信息
ngx_log_t            *log;             // 对应的log

void                 *ctx;             // 上下文(指向模块配置信息)
ngx_uint_t            module_type;     // 处理当前指令的模块类型:core、event、mail和http
ngx_uint_t            cmd_type;        // 当前指令的类型

ngx_conf_handler_pt   handler;         // 自定义的指令处理函数
char                 *handler_conf;    // 作为handler的参数,提供一些handler需要的配置信息
};


至此,基本的数据结构都看完了,开始学流程和机制吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: