Annotation of win32/apache22/srclib/apr-util/include/apr_hooks.h, revision 1.1
1.1 ! moko 1: /* Licensed to the Apache Software Foundation (ASF) under one or more
! 2: * contributor license agreements. See the NOTICE file distributed with
! 3: * this work for additional information regarding copyright ownership.
! 4: * The ASF licenses this file to You under the Apache License, Version 2.0
! 5: * (the "License"); you may not use this file except in compliance with
! 6: * the License. You may obtain a copy of the License at
! 7: *
! 8: * http://www.apache.org/licenses/LICENSE-2.0
! 9: *
! 10: * Unless required by applicable law or agreed to in writing, software
! 11: * distributed under the License is distributed on an "AS IS" BASIS,
! 12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! 13: * See the License for the specific language governing permissions and
! 14: * limitations under the License.
! 15: */
! 16:
! 17: #ifndef APR_HOOKS_H
! 18: #define APR_HOOKS_H
! 19:
! 20: #include "apu.h"
! 21: /* For apr_array_header_t */
! 22: #include "apr_tables.h"
! 23:
! 24: /**
! 25: * @file apr_hooks.h
! 26: * @brief Apache hook functions
! 27: */
! 28:
! 29: #ifdef __cplusplus
! 30: extern "C" {
! 31: #endif
! 32: /**
! 33: * @defgroup APR_Util_Hook Hook Functions
! 34: * @ingroup APR_Util
! 35: * @{
! 36: */
! 37:
! 38: /**
! 39: * @defgroup apr_hook_probes Hook probe capability
! 40: * APR hooks provide a trace probe capability for capturing
! 41: * the flow of control and return values with hooks.
! 42: *
! 43: * In order to use this facility, the application must define
! 44: * the symbol APR_HOOK_PROBES_ENABLED and the four APR_HOOK_PROBE_
! 45: * macros described below before including apr_hooks.h in files
! 46: * that use the APR_IMPLEMENT_EXTERNAL_HOOK_* macros.
! 47: *
! 48: * This probe facility is not provided for APR optional hooks.
! 49: * @{
! 50: */
! 51:
! 52: #ifdef APR_HOOK_PROBES_ENABLED
! 53: #define APR_HOOK_INT_DCL_UD void *ud = NULL
! 54: #else
! 55: /** internal implementation detail to avoid the ud declaration when
! 56: * hook probes are not used
! 57: */
! 58: #define APR_HOOK_INT_DCL_UD
! 59: /**
! 60: * User-defined hook probe macro that is invoked when the hook
! 61: * is run, before calling any hook functions.
! 62: * @param ud A void * user data field that should be filled in by
! 63: * this macro, and will be provided to the other hook probe macros.
! 64: * @param ns The namespace prefix of the hook functions
! 65: * @param name The name of the hook
! 66: * @param args The argument list to the hook functions, with enclosing
! 67: * parens.
! 68: */
! 69: #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
! 70: /**
! 71: * User-defined hook probe macro that is invoked after the hook
! 72: * has run.
! 73: * @param ud A void * user data field that was filled in by the user-
! 74: * provided APR_HOOK_PROBE_ENTRY().
! 75: * @param ns The namespace prefix of the hook functions
! 76: * @param name The name of the hook
! 77: * @param rv The return value of the hook, or 0 if the hook is void.
! 78: * @param args The argument list to the hook functions, with enclosing
! 79: * parens.
! 80: */
! 81: #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
! 82: /**
! 83: * User-defined hook probe macro that is invoked before calling a
! 84: * hook function.
! 85: * @param ud A void * user data field that was filled in by the user-
! 86: * provided APR_HOOK_PROBE_ENTRY().
! 87: * @param ns The namespace prefix of the hook functions
! 88: * @param name The name of the hook
! 89: * @param src The value of apr_hook_debug_current at the time the function
! 90: * was hooked (usually the source file implementing the hook function).
! 91: * @param args The argument list to the hook functions, with enclosing
! 92: * parens.
! 93: */
! 94: #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
! 95: /**
! 96: * User-defined hook probe macro that is invoked after calling a
! 97: * hook function.
! 98: * @param ud A void * user data field that was filled in by the user-
! 99: * provided APR_HOOK_PROBE_ENTRY().
! 100: * @param ns The namespace prefix of the hook functions
! 101: * @param name The name of the hook
! 102: * @param src The value of apr_hook_debug_current at the time the function
! 103: * was hooked (usually the source file implementing the hook function).
! 104: * @param rv The return value of the hook function, or 0 if the hook is void.
! 105: * @param args The argument list to the hook functions, with enclosing
! 106: * parens.
! 107: */
! 108: #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
! 109: #endif
! 110:
! 111: /** @} */
! 112:
! 113: /** macro to return the prototype of the hook function */
! 114: #define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
! 115: link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
! 116:
! 117: /** macro to declare the hook correctly */
! 118: #define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
! 119: typedef ret ns##_HOOK_##name##_t args; \
! 120: link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
! 121: const char * const *aszPre, \
! 122: const char * const *aszSucc, int nOrder); \
! 123: link##_DECLARE(ret) ns##_run_##name args; \
! 124: APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
! 125: typedef struct ns##_LINK_##name##_t \
! 126: { \
! 127: ns##_HOOK_##name##_t *pFunc; \
! 128: const char *szName; \
! 129: const char * const *aszPredecessors; \
! 130: const char * const *aszSuccessors; \
! 131: int nOrder; \
! 132: } ns##_LINK_##name##_t;
! 133:
! 134: /** macro to declare the hook structure */
! 135: #define APR_HOOK_STRUCT(members) \
! 136: static struct { members } _hooks;
! 137:
! 138: /** macro to link the hook structure */
! 139: #define APR_HOOK_LINK(name) \
! 140: apr_array_header_t *link_##name;
! 141:
! 142: /** macro to implement the hook */
! 143: #define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
! 144: link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
! 145: const char * const *aszSucc,int nOrder) \
! 146: { \
! 147: ns##_LINK_##name##_t *pHook; \
! 148: if(!_hooks.link_##name) \
! 149: { \
! 150: _hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
! 151: apr_hook_sort_register(#name,&_hooks.link_##name); \
! 152: } \
! 153: pHook=apr_array_push(_hooks.link_##name); \
! 154: pHook->pFunc=pf; \
! 155: pHook->aszPredecessors=aszPre; \
! 156: pHook->aszSuccessors=aszSucc; \
! 157: pHook->nOrder=nOrder; \
! 158: pHook->szName=apr_hook_debug_current; \
! 159: if(apr_hook_debug_enabled) \
! 160: apr_hook_debug_show(#name,aszPre,aszSucc); \
! 161: } \
! 162: APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
! 163: { \
! 164: return _hooks.link_##name; \
! 165: }
! 166:
! 167: /**
! 168: * Implement a hook that has no return code, and therefore runs all of the
! 169: * registered functions
! 170: * @param ns The namespace prefix of the hook functions
! 171: * @param link The linkage declaration prefix of the hook
! 172: * @param name The name of the hook
! 173: * @param args_decl The declaration of the arguments for the hook
! 174: * @param args_use The names for the arguments for the hook
! 175: * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
! 176: * provide export linkage from the module that IMPLEMENTs the hook, and
! 177: * import linkage from external modules that link to the hook's module.
! 178: */
! 179: #define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
! 180: APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
! 181: link##_DECLARE(void) ns##_run_##name args_decl \
! 182: { \
! 183: ns##_LINK_##name##_t *pHook; \
! 184: int n; \
! 185: APR_HOOK_INT_DCL_UD; \
! 186: \
! 187: APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
! 188: \
! 189: if(_hooks.link_##name) \
! 190: { \
! 191: pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
! 192: for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
! 193: { \
! 194: APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
! 195: pHook[n].pFunc args_use; \
! 196: APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, 0, args_use); \
! 197: } \
! 198: } \
! 199: \
! 200: APR_HOOK_PROBE_RETURN(ud, ns, name, 0, args_use); \
! 201: \
! 202: }
! 203:
! 204: /* FIXME: note that this returns ok when nothing is run. I suspect it should
! 205: really return decline, but that breaks Apache currently - Ben
! 206: */
! 207: /**
! 208: * Implement a hook that runs until one of the functions returns something
! 209: * other than OK or DECLINE
! 210: * @param ns The namespace prefix of the hook functions
! 211: * @param link The linkage declaration prefix of the hook
! 212: * @param ret Type to return
! 213: * @param name The name of the hook
! 214: * @param args_decl The declaration of the arguments for the hook
! 215: * @param args_use The names for the arguments for the hook
! 216: * @param ok Success value
! 217: * @param decline Decline value
! 218: * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
! 219: * provide export linkage from the module that IMPLEMENTs the hook, and
! 220: * import linkage from external modules that link to the hook's module.
! 221: */
! 222: #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
! 223: APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
! 224: link##_DECLARE(ret) ns##_run_##name args_decl \
! 225: { \
! 226: ns##_LINK_##name##_t *pHook; \
! 227: int n; \
! 228: ret rv = ok; \
! 229: APR_HOOK_INT_DCL_UD; \
! 230: \
! 231: APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
! 232: \
! 233: if(_hooks.link_##name) \
! 234: { \
! 235: pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
! 236: for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
! 237: { \
! 238: APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
! 239: rv=pHook[n].pFunc args_use; \
! 240: APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
! 241: if(rv != ok && rv != decline) \
! 242: break; \
! 243: rv = ok; \
! 244: } \
! 245: } \
! 246: \
! 247: APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
! 248: \
! 249: return rv; \
! 250: }
! 251:
! 252:
! 253: /**
! 254: * Implement a hook that runs until the first function returns something
! 255: * other than the value of decline
! 256: * @param ns The namespace prefix of the hook functions
! 257: * @param link The linkage declaration prefix of the hook
! 258: * @param name The name of the hook
! 259: * @param ret Type to return
! 260: * @param args_decl The declaration of the arguments for the hook
! 261: * @param args_use The names for the arguments for the hook
! 262: * @param decline Decline value
! 263: * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
! 264: * provide export linkage from the module that IMPLEMENTs the hook, and
! 265: * import linkage from external modules that link to the hook's module.
! 266: */
! 267: #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \
! 268: APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
! 269: link##_DECLARE(ret) ns##_run_##name args_decl \
! 270: { \
! 271: ns##_LINK_##name##_t *pHook; \
! 272: int n; \
! 273: ret rv = decline; \
! 274: APR_HOOK_INT_DCL_UD; \
! 275: \
! 276: APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
! 277: \
! 278: if(_hooks.link_##name) \
! 279: { \
! 280: pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
! 281: for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
! 282: { \
! 283: APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
! 284: rv=pHook[n].pFunc args_use; \
! 285: APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
! 286: \
! 287: if(rv != decline) \
! 288: break; \
! 289: } \
! 290: } \
! 291: \
! 292: APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
! 293: \
! 294: return rv; \
! 295: }
! 296:
! 297: /* Hook orderings */
! 298: /** run this hook first, before ANYTHING */
! 299: #define APR_HOOK_REALLY_FIRST (-10)
! 300: /** run this hook first */
! 301: #define APR_HOOK_FIRST 0
! 302: /** run this hook somewhere */
! 303: #define APR_HOOK_MIDDLE 10
! 304: /** run this hook after every other hook which is defined*/
! 305: #define APR_HOOK_LAST 20
! 306: /** run this hook last, after EVERYTHING */
! 307: #define APR_HOOK_REALLY_LAST 30
! 308:
! 309: /**
! 310: * The global pool used to allocate any memory needed by the hooks.
! 311: */
! 312: APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool;
! 313:
! 314: /**
! 315: * A global variable to determine if debugging information about the
! 316: * hooks functions should be printed
! 317: */
! 318: APU_DECLARE_DATA extern int apr_hook_debug_enabled;
! 319:
! 320: /**
! 321: * The name of the module that is currently registering a function
! 322: */
! 323: APU_DECLARE_DATA extern const char *apr_hook_debug_current;
! 324:
! 325: /**
! 326: * Register a hook function to be sorted
! 327: * @param szHookName The name of the Hook the function is registered for
! 328: * @param aHooks The array which stores all of the functions for this hook
! 329: */
! 330: APU_DECLARE(void) apr_hook_sort_register(const char *szHookName,
! 331: apr_array_header_t **aHooks);
! 332: /**
! 333: * Sort all of the registerd functions for a given hook
! 334: */
! 335: APU_DECLARE(void) apr_hook_sort_all(void);
! 336:
! 337: /**
! 338: * Print all of the information about the current hook. This is used for
! 339: * debugging purposes.
! 340: * @param szName The name of the hook
! 341: * @param aszPre All of the functions in the predecessor array
! 342: * @param aszSucc All of the functions in the successor array
! 343: */
! 344: APU_DECLARE(void) apr_hook_debug_show(const char *szName,
! 345: const char * const *aszPre,
! 346: const char * const *aszSucc);
! 347:
! 348: /**
! 349: * Remove all currently registered functions.
! 350: */
! 351: APU_DECLARE(void) apr_hook_deregister_all(void);
! 352:
! 353: /** @} */
! 354: #ifdef __cplusplus
! 355: }
! 356: #endif
! 357:
! 358: #endif /* APR_HOOKS_H */
E-mail: