blob: 8b5395580a93c5969c2226c18fde063b9b424ee8 [file] [log] [blame]
#ifndef APACHE_AP_HOOKS_H
#define APACHE_AP_HOOKS_H
#define DECLARE_HOOK(ret,name,args) \
typedef ret HOOK_##name args; \
void ap_hook_##name(HOOK_##name *pf,const char * const *aszPre, \
const char * const *aszSucc,int nOrder); \
ret ap_run_##name args; \
typedef struct _LINK_##name \
{ \
HOOK_##name *pFunc; \
const char *szName; \
const char * const *aszPredecessors; \
const char * const *aszSuccessors; \
int nOrder; \
} LINK_##name;
#define HOOK_STRUCT(members) \
static struct { members } _hooks;
#define HOOK_LINK(name) \
ap_array_header_t *link_##name;
#define IMPLEMENT_HOOK_BASE(name) \
void ap_hook_##name(HOOK_##name *pf,const char * const *aszPre, \
const char * const *aszSucc,int nOrder) \
{ \
LINK_##name *pHook; \
if(!_hooks.link_##name) \
{ \
_hooks.link_##name=ap_make_array(g_pHookPool,1,sizeof(LINK_##name)); \
ap_hook_sort_register(#name,&_hooks.link_##name); \
} \
pHook=ap_push_array(_hooks.link_##name); \
pHook->pFunc=pf; \
pHook->aszPredecessors=aszPre; \
pHook->aszSuccessors=aszSucc; \
pHook->nOrder=nOrder; \
pHook->szName=g_szCurrentHookName; \
if(g_bDebugHooks) \
ap_show_hook(#name,aszPre,aszSucc); \
}
/* RUN_ALL runs to the first one to return other than ok or decline
RUN_FIRST runs to the first one to return other than decline
VOID runs all
*/
#define IMPLEMENT_HOOK_VOID(name,args_decl,args_use) \
IMPLEMENT_HOOK_BASE(name) \
void ap_run_##name args_decl \
{ \
LINK_##name *pHook; \
int n; \
\
if(!_hooks.link_##name) \
return; \
\
pHook=(LINK_##name *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
pHook[n].pFunc args_use; \
}
/* FIXME: note that this returns ok when nothing is run. I suspect it should
really return decline, but that breaks Apache currently - Ben
*/
#define IMPLEMENT_HOOK_RUN_ALL(ret,name,args_decl,args_use,ok,decline) \
IMPLEMENT_HOOK_BASE(name) \
ret ap_run_##name args_decl \
{ \
LINK_##name *pHook; \
int n; \
ret rv; \
\
if(!_hooks.link_##name) \
return ok; \
\
pHook=(LINK_##name *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
{ \
rv=pHook[n].pFunc args_use; \
\
if(rv != ok && rv != decline) \
return rv; \
} \
return ok; \
}
#define IMPLEMENT_HOOK_RUN_FIRST(ret,name,args_decl,args_use,decline) \
IMPLEMENT_HOOK_BASE(name) \
ret ap_run_##name args_decl \
{ \
LINK_##name *pHook; \
int n; \
ret rv; \
\
if(!_hooks.link_##name) \
return decline; \
\
pHook=(LINK_##name *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
{ \
rv=pHook[n].pFunc args_use; \
\
if(rv != decline) \
return rv; \
} \
return decline; \
}
/* Hook orderings */
#define HOOK_REALLY_FIRST (-10)
#define HOOK_FIRST 0
#define HOOK_MIDDLE 10
#define HOOK_LAST 20
#define HOOK_REALLY_LAST 30
extern ap_pool_t *g_pHookPool;
extern int g_bDebugHooks;
extern const char *g_szCurrentHookName;
void ap_hook_sort_register(const char *szHookName, ap_array_header_t **aHooks);
void ap_sort_hooks(void);
void ap_show_hook(const char *szName,const char * const *aszPre,
const char * const *aszSucc);
#endif /* ndef(AP_HOOKS_H) */