apr_array_header_t *link_post_config;
apr_array_header_t *link_open_logs;
apr_array_header_t *link_child_init;
apr_array_header_t *link_handler;
apr_array_header_t *link_quick_handler;
apr_array_header_t *link_optional_fn_retrieve;
}_hook;
因此任何对挂钩数组的访问都必须通过_hook来实现。比如我们在某个模块中使用挂钩post_config,那么在数组中增加数据可以用下面的代码:
ap_LINK_post_config_t *pHook;
if (!_hooks.link_post_config) {
_hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1,
sizeof(ap_LINK_post_config_t));
apr_hook_sort_register("post_config", &_hooks.link_post_config);
}
pHook = apr_array_push(_hooks.link_post_config);
pHook->pFunc = …;
pHook->aszPredecessors = …;
pHook->aszSuccessors = …;
pHook->nOrder = …;
pHook->szName = …;
不过有几点必须注意的是:
(1)、_hook在某个文件中如果定义,则只能定义一次。该文件中使用的定义的挂钩数组统统添加到该结构中,正所谓“大肚能容,容天下难容之事”。
(2)、_hook的定义为static,这意味这该结构实际上是模块内部的私有结构,外部模块无法直接访问_hook结构,而且_hook结构不仅仅在一个文件中出现,只要实现了挂钩,按道理就应该有一个_hook结构。尽管如此,由于static属性,它们相互之间“绝缘”,不会相互干扰。
(3)、当某个模块想使用某个挂钩,比如post_config的时候,其一不能直接访问post_config挂钩数组,二不能访问被屏蔽的模块内_hook,那么它应该怎么办呢?它只能使用挂钩注册函数。正如前面所述,挂钩注册函数通常形如ap_hook_name。比如模块需要使用post_config挂钩,其必须调用ap_hook_post_config进行注册。现在如果我们将在编写模块的时候遇到类似下面的代码,你就不会纳闷了:
static void register_hooks(apr_pool_t *p)
{
ap_hook_handler(status_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_config(status_init, NULL, NULL, APR_HOOK_MIDDLE);
}
register_hooks是模块mod_status.c中的挂钩注册函数,在该模块中,Apache注册了两个挂钩:handler和status_init,分别对应的挂钩函数为status_handler和status_init。