#define APR_OPTIONAL_HOOK(ns,name,pfn,aszPre,aszSucc,nOrder) do { \
ns##_HOOK_##name##_t *apu__hook = pfn; \
apr_optional_hook_add(#name,(void (*)(void))apu__hook,aszPre, aszSucc, nOrder); \
} while (0)
5.5.7.3 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL
对于标准挂钩,其实现分为VOID、FIRST和ALL三种,而对于可选挂钩,实现则归结只有一种ALL类型,即APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL,该宏定义如下:
#define APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
link##_DECLARE(ret) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
ret rv; \
apr_array_header_t *pHookArray=apr_optional_hook_get(#name); \
if(!pHookArray) \
return ok; \
pHook=(ns##_LINK_##name##_t *)pHookArray->elts; \
for(n=0 ; n < pHookArray->nelts ; ++n) \
{ \
rv=(pHook[n].pFunc)args_use; \
\
if(rv != ok && rv != decline) \
return rv; \
} \
return ok; \
}
在status模块mod_status.c中我们声明的挂钩status_hook就是一个可选挂钩,该挂钩实现如下:
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook,
(request_rec *r, int flags),
(r, flags),
OK, DECLINED)
该宏展开后即实现了ap_run_status_hook函数,其实现过程,即展开结果如下所示: