标签:
它的实现非常easy。以下是该模块的定义:
ngx_module_t ngx_events_module = { NGX_MODULE_V1, &ngx_events_module_ctx, /* module context */ ngx_events_commands, /* module directives */ NGX_CORE_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING };
// 定义了怎样处理感兴趣的配置项 static ngx_command_t ngx_events_commands[] = { { ngx_string("events"), /* 仅仅对events块配置项感兴趣 */ NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_events_block, /* 解析配置项的函数 */ 0, 0, NULL }, ngx_null_command };
static ngx_core_module_t ngx_events_module_ctx = { ngx_string("events"), NULL, /* create_conf */ ngx_event_init_conf /* init_conf */ };
这是由于ngx_events_module并不解析配置项參数,仅仅是在events块配置项出现后调用各个事件模块去解析events内的配置项,所以它自己并不须要实现create_conf方法和init_conf方法。
typedef struct { ngx_str_t *name; // 事件模块名字 // 解析配置项之前调用,创建存储配置项參数的结构体 void *(*create_conf)(ngx_cycle_t *cycle); // 解析完配置项后的回调函数 char *(*init_conf)(ngx_cycle_t *cycle, void *conf); // 每一个事件模块须要实现的10个抽象方法 ngx_event_actions_t actions; } ngx_event_module_t; // 事件模块通用接口
这个指针放在了ngx_events_module核心模块创建的指针数组中,例如以下图所看到的:
static char * ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; void ***ctx; ngx_uint_t i; ngx_conf_t pcf; ngx_event_module_t *m; ngx_event_max_module = 0; for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_EVENT_MODULE) continue; /* 1.初始化全部事件模块的ctx_index成员 * 该成员表明了该模块在同样类型模块中的顺序。这会决定以后载入各事件模块的顺序 */ ngx_modules[i]->ctx_index = ngx_event_max_module++; } /* 分配一个存放指针的空间 */ ctx = ngx_pcalloc(cf->pool, sizeof(void *)); /* 2.ngx_event_max_module等于事件模块个数 */ *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)); *(void **) conf = ctx; /* conf指向存储參数的结构体 */ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_EVENT_MODULE) continue; m = ngx_modules[i]->ctx; /* 得到事件模块的通用接口 */ if (m->create_conf) /* 3.调用全部事件模块的通用接口ngx_event_module_t中的create_conf方法 */ (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle); } pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE; cf->cmd_type = NGX_EVENT_CONF; /* 4.针对全部事件模块调用各自的解析配置文件的方法 * 当发现对应配置项后。就调用模块中ngx_command_t数组中的方法 */ rv = ngx_conf_parse(cf, NULL); /* cf中保存有读到的配置项參数 */ *cf = pcf; for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_EVENT_MODULE) continue; m = ngx_modules[i]->ctx; if (m->init_conf) /* 5.解析完配置项后,调用每一个模块的init_conf方法对配置參数进行整合 */ rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]); } return NGX_CONF_OK; }
事件驱动机制很多其它的工作是在ngx_event_core_module模块中完毕,下次再写。
标签:
原文地址:http://www.cnblogs.com/gcczhongduan/p/5321887.html