Apache Portable Runtime
apr_hooks.h
Go to the documentation of this file.
00001 /* Licensed to the Apache Software Foundation (ASF) under one or more
00002  * contributor license agreements.  See the NOTICE file distributed with
00003  * this work for additional information regarding copyright ownership.
00004  * The ASF licenses this file to You under the Apache License, Version 2.0
00005  * (the "License"); you may not use this file except in compliance with
00006  * the License.  You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef APR_HOOKS_H
00018 #define APR_HOOKS_H
00019 
00020 #include "apu.h"
00021 /* For apr_array_header_t */
00022 #include "apr_tables.h"
00023 
00024 /**
00025  * @file apr_hooks.h
00026  * @brief Apache hook functions
00027  */
00028 
00029 #ifdef __cplusplus
00030 extern "C" {
00031 #endif
00032 /**
00033  * @defgroup APR_Util_Hook Hook Functions
00034  * @ingroup APR_Util
00035  * @{
00036  */
00037 /** macro to return the prototype of the hook function */    
00038 #define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
00039 link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
00040 
00041 /** macro to declare the hook correctly */    
00042 #define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
00043 typedef ret ns##_HOOK_##name##_t args; \
00044 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
00045                                       const char * const *aszPre, \
00046                                       const char * const *aszSucc, int nOrder); \
00047 link##_DECLARE(ret) ns##_run_##name args; \
00048 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
00049 typedef struct ns##_LINK_##name##_t \
00050     { \
00051     ns##_HOOK_##name##_t *pFunc; \
00052     const char *szName; \
00053     const char * const *aszPredecessors; \
00054     const char * const *aszSuccessors; \
00055     int nOrder; \
00056     } ns##_LINK_##name##_t;
00057 
00058 /** macro to declare the hook structure */    
00059 #define APR_HOOK_STRUCT(members) \
00060 static struct { members } _hooks;
00061 
00062 /** macro to link the hook structure */
00063 #define APR_HOOK_LINK(name) \
00064     apr_array_header_t *link_##name;
00065 
00066 /** macro to implement the hook */
00067 #define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00068 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
00069                                       const char * const *aszSucc,int nOrder) \
00070     { \
00071     ns##_LINK_##name##_t *pHook; \
00072     if(!_hooks.link_##name) \
00073         { \
00074         _hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
00075         apr_hook_sort_register(#name,&_hooks.link_##name); \
00076         } \
00077     pHook=apr_array_push(_hooks.link_##name); \
00078     pHook->pFunc=pf; \
00079     pHook->aszPredecessors=aszPre; \
00080     pHook->aszSuccessors=aszSucc; \
00081     pHook->nOrder=nOrder; \
00082     pHook->szName=apr_hook_debug_current; \
00083     if(apr_hook_debug_enabled) \
00084         apr_hook_debug_show(#name,aszPre,aszSucc); \
00085     } \
00086     APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
00087     { \
00088         return _hooks.link_##name; \
00089     }
00090 
00091 /**
00092  * Implement a hook that has no return code, and therefore runs all of the
00093  * registered functions
00094  * @param ns The namespace prefix of the hook functions
00095  * @param link The linkage declaration prefix of the hook
00096  * @param name The name of the hook
00097  * @param args_decl The declaration of the arguments for the hook
00098  * @param args_use The names for the arguments for the hook
00099  * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
00100  * provide export linkage from the module that IMPLEMENTs the hook, and
00101  * import linkage from external modules that link to the hook's module.
00102  */
00103 #define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
00104 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00105 link##_DECLARE(void) ns##_run_##name args_decl \
00106     { \
00107     ns##_LINK_##name##_t *pHook; \
00108     int n; \
00109 \
00110     if(!_hooks.link_##name) \
00111         return; \
00112 \
00113     pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00114     for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00115         pHook[n].pFunc args_use; \
00116     }
00117 
00118 /* FIXME: note that this returns ok when nothing is run. I suspect it should
00119    really return decline, but that breaks Apache currently - Ben
00120 */
00121 /**
00122  * Implement a hook that runs until one of the functions returns something
00123  * other than OK or DECLINE
00124  * @param ns The namespace prefix of the hook functions
00125  * @param link The linkage declaration prefix of the hook
00126  * @param ret Type to return
00127  * @param name The name of the hook
00128  * @param args_decl The declaration of the arguments for the hook
00129  * @param args_use The names for the arguments for the hook
00130  * @param ok Success value
00131  * @param decline Decline value
00132  * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
00133  * provide export linkage from the module that IMPLEMENTs the hook, and
00134  * import linkage from external modules that link to the hook's module.
00135  */
00136 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
00137 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00138 link##_DECLARE(ret) ns##_run_##name args_decl \
00139     { \
00140     ns##_LINK_##name##_t *pHook; \
00141     int n; \
00142     ret rv; \
00143 \
00144     if(!_hooks.link_##name) \
00145         return ok; \
00146 \
00147     pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00148     for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00149         { \
00150         rv=pHook[n].pFunc args_use; \
00151 \
00152         if(rv != ok && rv != decline) \
00153             return rv; \
00154         } \
00155     return ok; \
00156     }
00157 
00158 
00159 /**
00160  * Implement a hook that runs until the first function returns something
00161  * other than the value of decline
00162  * @param ns The namespace prefix of the hook functions
00163  * @param link The linkage declaration prefix of the hook
00164  * @param name The name of the hook
00165  * @param ret Type to return
00166  * @param args_decl The declaration of the arguments for the hook
00167  * @param args_use The names for the arguments for the hook
00168  * @param decline Decline value
00169  * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
00170  * provide export linkage from the module that IMPLEMENTs the hook, and
00171  * import linkage from external modules that link to the hook's module.
00172  */
00173 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \
00174 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
00175 link##_DECLARE(ret) ns##_run_##name args_decl \
00176     { \
00177     ns##_LINK_##name##_t *pHook; \
00178     int n; \
00179     ret rv; \
00180 \
00181     if(!_hooks.link_##name) \
00182         return decline; \
00183 \
00184     pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
00185     for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
00186         { \
00187         rv=pHook[n].pFunc args_use; \
00188 \
00189         if(rv != decline) \
00190             return rv; \
00191         } \
00192     return decline; \
00193     }
00194 
00195     /* Hook orderings */
00196 /** run this hook first, before ANYTHING */
00197 #define APR_HOOK_REALLY_FIRST   (-10)
00198 /** run this hook first */
00199 #define APR_HOOK_FIRST          0
00200 /** run this hook somewhere */
00201 #define APR_HOOK_MIDDLE         10
00202 /** run this hook after every other hook which is defined*/
00203 #define APR_HOOK_LAST           20
00204 /** run this hook last, after EVERYTHING */
00205 #define APR_HOOK_REALLY_LAST    30
00206 
00207 /**
00208  * The global pool used to allocate any memory needed by the hooks.
00209  */ 
00210 APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool;
00211 
00212 /**
00213  * A global variable to determine if debugging information about the
00214  * hooks functions should be printed
00215  */ 
00216 APU_DECLARE_DATA extern int apr_hook_debug_enabled;
00217 
00218 /**
00219  * The name of the module that is currently registering a function
00220  */ 
00221 APU_DECLARE_DATA extern const char *apr_hook_debug_current;
00222 
00223 /**
00224  * Register a hook function to be sorted
00225  * @param szHookName The name of the Hook the function is registered for
00226  * @param aHooks The array which stores all of the functions for this hook
00227  */
00228 APU_DECLARE(void) apr_hook_sort_register(const char *szHookName, 
00229                                         apr_array_header_t **aHooks);
00230 /**
00231  * Sort all of the registerd functions for a given hook
00232  */
00233 APU_DECLARE(void) apr_hook_sort_all(void);
00234 
00235 /**
00236  * Print all of the information about the current hook.  This is used for
00237  * debugging purposes.
00238  * @param szName The name of the hook
00239  * @param aszPre All of the functions in the predecessor array
00240  * @param aszSucc All of the functions in the successor array
00241  */
00242 APU_DECLARE(void) apr_hook_debug_show(const char *szName,
00243                                       const char * const *aszPre,
00244                                       const char * const *aszSucc);
00245 
00246 /**
00247  * Remove all currently registered functions.
00248  */
00249 APU_DECLARE(void) apr_hook_deregister_all(void);
00250 
00251 /** @} */
00252 #ifdef __cplusplus
00253 }
00254 #endif
00255 
00256 #endif /* APR_HOOKS_H */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines