00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef APR_HOOKS_H
00018 #define APR_HOOKS_H
00019
00020 #include "apu.h"
00021
00022 #include "apr_tables.h"
00023
00024 #ifdef APR_DTRACE_PROVIDER
00025 #include <sys/sdt.h>
00026 #ifndef OLD_DTRACE_PROBE
00027 #define OLD_DTRACE_PROBE(name) __dtrace_ap___##name()
00028 #endif
00029 #ifndef OLD_DTRACE_PROBE1
00030 #define OLD_DTRACE_PROBE1(name,a) __dtrace_ap___##name(a)
00031 #endif
00032 #ifndef OLD_DTRACE_PROBE2
00033 #define OLD_DTRACE_PROBE2(name,a,b) __dtrace_ap___##name(a,b)
00034 #endif
00035 #else
00036 #define OLD_DTRACE_PROBE(a)
00037 #define OLD_DTRACE_PROBE1(a,b)
00038 #define OLD_DTRACE_PROBE2(a,b,c)
00039 #endif
00040
00046 #ifdef __cplusplus
00047 extern "C" {
00048 #endif
00049
00055 #define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
00056 link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
00057
00059 #define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
00060 typedef ret ns##_HOOK_##name##_t args; \
00061 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
00062 const char * const *aszPre, \
00063 const char * const *aszSucc, int nOrder); \
00064 link##_DECLARE(ret) ns##_run_##name args; \
00065 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
00066 typedef struct ns##_LINK_##name##_t \
00067 { \
00068 ns##_HOOK_##name##_t *pFunc; \
00069 const char *szName; \
00070 const char * const *aszPredecessors; \
00071 const char * const *aszSuccessors; \
00072 int nOrder; \
00073 } ns##_LINK_##name##_t;
00074
00076 #define APR_HOOK_STRUCT(members) \
00077 static struct { members } _hooks;
00078
00080 #define APR_HOOK_LINK(name) \
00081 apr_array_header_t *link_##name;
00082
00084 #define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00085 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
00086 const char * const *aszSucc,int nOrder) \
00087 { \
00088 ns##_LINK_##name##_t *pHook; \
00089 if(!_hooks.link_##name) \
00090 { \
00091 _hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
00092 apr_hook_sort_register(#name,&_hooks.link_##name); \
00093 } \
00094 pHook=apr_array_push(_hooks.link_##name); \
00095 pHook->pFunc=pf; \
00096 pHook->aszPredecessors=aszPre; \
00097 pHook->aszSuccessors=aszSucc; \
00098 pHook->nOrder=nOrder; \
00099 pHook->szName=apr_hook_debug_current; \
00100 if(apr_hook_debug_enabled) \
00101 apr_hook_debug_show(#name,aszPre,aszSucc); \
00102 } \
00103 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
00104 { \
00105 return _hooks.link_##name; \
00106 }
00107
00120 #define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
00121 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00122 link##_DECLARE(void) ns##_run_##name args_decl \
00123 { \
00124 ns##_LINK_##name##_t *pHook; \
00125 int n; \
00126 \
00127 OLD_DTRACE_PROBE(name##__entry); \
00128 \
00129 if(_hooks.link_##name) \
00130 { \
00131 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00132 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00133 { \
00134 OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
00135 pHook[n].pFunc args_use; \
00136 OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, 0); \
00137 } \
00138 } \
00139 \
00140 OLD_DTRACE_PROBE1(name##__return, 0); \
00141 \
00142 }
00143
00144
00145
00146
00162 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
00163 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00164 link##_DECLARE(ret) ns##_run_##name args_decl \
00165 { \
00166 ns##_LINK_##name##_t *pHook; \
00167 int n; \
00168 ret rv = ok; \
00169 \
00170 OLD_DTRACE_PROBE(name##__entry); \
00171 \
00172 if(_hooks.link_##name) \
00173 { \
00174 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00175 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00176 { \
00177 OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
00178 rv=pHook[n].pFunc args_use; \
00179 OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, rv); \
00180 if(rv != ok && rv != decline) \
00181 break; \
00182 rv = ok; \
00183 } \
00184 } \
00185 \
00186 OLD_DTRACE_PROBE1(name##__return, rv); \
00187 \
00188 return rv; \
00189 }
00190
00191
00206 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \
00207 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00208 link##_DECLARE(ret) ns##_run_##name args_decl \
00209 { \
00210 ns##_LINK_##name##_t *pHook; \
00211 int n; \
00212 ret rv = decline; \
00213 \
00214 OLD_DTRACE_PROBE(name##__entry); \
00215 \
00216 if(_hooks.link_##name) \
00217 { \
00218 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00219 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00220 { \
00221 OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
00222 rv=pHook[n].pFunc args_use; \
00223 OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, rv); \
00224 \
00225 if(rv != decline) \
00226 break; \
00227 } \
00228 } \
00229 \
00230 OLD_DTRACE_PROBE1(name##__return, rv); \
00231 \
00232 return rv; \
00233 }
00234
00235
00237 #define APR_HOOK_REALLY_FIRST (-10)
00238
00239 #define APR_HOOK_FIRST 0
00240
00241 #define APR_HOOK_MIDDLE 10
00242
00243 #define APR_HOOK_LAST 20
00244
00245 #define APR_HOOK_REALLY_LAST 30
00246
00250 APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool;
00251
00256 APU_DECLARE_DATA extern int apr_hook_debug_enabled;
00257
00261 APU_DECLARE_DATA extern const char *apr_hook_debug_current;
00262
00268 APU_DECLARE(void) apr_hook_sort_register(const char *szHookName,
00269 apr_array_header_t **aHooks);
00273 APU_DECLARE(void) apr_hook_sort_all(void);
00274
00282 APU_DECLARE(void) apr_hook_debug_show(const char *szName,
00283 const char * const *aszPre,
00284 const char * const *aszSucc);
00285
00289 APU_DECLARE(void) apr_hook_deregister_all(void);
00290
00292 #ifdef __cplusplus
00293 }
00294 #endif
00295
00296 #endif