\
if(!_hooks.link_##name) \
return; \
\
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
pHook[n].pFunc args_use; \
}
比如对于config.c中的child_init挂钩,其就是VOID类型,声明语句如下:
AP_IMPLEMENT_HOOK_VOID(child_init,
(apr_pool_t *pchild, server_rec *s),
(pchild, s))
撇去APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name)不管,这里我们仅仅关心剩下的的展开结果,如下:
AP_DECLARE(void) ap_run_child_init(apr_pool_t *pchild,server_rec* s)
{
ap_LINK_child_init_t pHook;
int n;
if(!_hooks.link_child_init)
return;
pHook=(ap_LINK_child_init_t)_hooks.link_child_init->elts;
for(n=0;n<_hooks.link_child_init->nelts;++n)
pHook[n].pFunc(pchild, s);
}
从展开结果可以看出,即使在逐次调用过程中发生了错误,调用也不会停止,它就是“一头拉不回头的牛”。
(2)、AP_IMPLEMENT_HOOK_ALL简称ALL类型,其与AP_IMPLEMENT_HOOK_VOID几乎相同,唯一不同的就是ALL类型具有返回值。宏声明如下:
#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(ret) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
ret rv; \
\
if(!_hooks.link_##name) \