/*
* SYNOPSIS
*
* Main Setup:
* void ap_hook_init (void);
* void ap_hook_kill (void);
*
* Hook Configuration and Registration:
* ap_hook_define_client(hook_name,hook_parameters,hook_call);
* int ap_hook_configure_hook_name(ap_hook_mode modeid);
* int ap_hook_unconfigure_hook_name();
*
* ap_hook_define_server(hook_name,hook_parameters,hook_call);
* int ap_hook_register_hook_name(int (*func)hook_parameters);
* int ap_hook_unregister_hook_name(int (*func)hook_parameters);
*
* ap_hook_define_client_global(mod_name,hook_name,hook_parameters,hook_call);
* ap_hook_define_client_realize(mod_name,hook_name,hook_parameters,hook_call);
* int ap_hook_mod_name_configure_hook_name(ap_hook_mode modeid);
* int ap_hook_mod_name_unconfigure_hook_name();
*
* ap_hook_define_server_global(mod_name,hook_name,hook_parameters,hook_call);
* ap_hook_define_server_realize(mod_name,hook_name,hook_parameters,hook_call);
* int ap_hook_mod_name_register_hook_name(int (*func)hook_parameters);
* int ap_hook_mod_name_unregister_hook_name(int (*func)hook_parameters);
*
* Hook Usage:
* int ap_hook_configured_hook_name();
* int ap_hook_registered_hook_name();
* int ap_hook_registered_func_hook_name(int (*func)hook_parameters);
* int ap_hook_hook_name(hook_parameters);
*
* int ap_hook_mod_name_configured_hook_name();
* int ap_hook_mod_name_registered_hook_name();
* int ap_hook_mod_name_registered_func_hook_name(int (*func)hook_parameters);
* int ap_hook_mod_name_hook_name(hook_parameters);
*
* DESCRIPTION
*
* This implements a generic hook interface for Apache which can be used
* for loosely couple code through arbitrary hooks. There are two use cases
* for this mechanism:
*
* 1. Inside a specific code section you want to perform a specific
* function call. But you want to allow one or even more modules to
* override this function call by registering hook functions. Those
* functions are registered on a stack and could return TRUE or FALSE.
* As long as there are functions which return FALSE value the next
* function on the stack is tried. When a function return TRUE the
* hook call stops. The intent of this usage is to not hard-code
* function calls. Note that the only return type allowed for hooks
* is int and only two values could be returned: TRUE and FALSE. If
* you want other return types or values use wrappers (see sample below).
*
* 2. Inside a specific code you have a function you want to export.
* But you first want to allow other code to override this function.
* And second you want to export this function without real linker
* symbol references. Instead you want to register the function and let
* the users call this function via name. The intent of this usage is to
* allow inter-module communication without direct symbol references,
* which are a big NO-NO for the DSO situation.
*
* And we have one major design goal: The hook call should be very similar
* to the corresponding direct function call while still providing maximum
* flexiblity, i.e. any function signature (the set of types for arguments)
* should be supported. If you need return value use wrappers.
*
* Using this hook interface is always a four-step process(but see also
* "NOTE for DSO modules" below!):
*
* 1. Initialize or destroy the hook mechanism inside your main program:
*
* ap_hook_init();
* :
* ap_hook_kill();
*
* 2. Define and configure a particular hook by specifing its name and
* argumets type:
*
* ap_hook_define_client(lookup,(void **r,void *x),(r,x));
* ap_hook_define_client(echo,(int *r,void *x),(r,x));
*
* ap_hook_configure_lookup(AP_HOOK_NORMAL);
* ap_hook_configure_echo(AP_HOOK_TOPMOST);
*
* This configures two hooks:
* - A hook named "lookup" with the signature "lookup(void **,void *)"
* and default return semantic.
* - A hook named "echo" with the signature "echo(int *,void *)" and a
* return code semantic which says: Only the top most function on the
* registered function stack is tried, independed what value it
* returns.
*
* 3. Define and register the actual functions which should be used by
* the hook:
*
* ap_hook_define_server(lookup,(void **r,void *x),(r,x));
* ap_hook_define_server(echo,(int *r,void *x),(r,x));
*
* static int mylookup_wrapper(void **r,void *x) {
* *r=mylookup(x);
* if (*r) return TRUE; else return FALSE;
* }
* static int myecho_wrapper(int *r,void *x) {
* *r=myecho(*r,x);
* return TRUE;
* }
*
* ap_hook_register_lookup(mylookup);
* ap_hook_register_echo(myecho);
*
* This registers the function mylookup() under the "lookup" hook and
* function myecho() under the "echo" hook.
*
* 4. Finally use the hook, i.e. instead of using direct function calls
* like
*
* vp = mylookup("foo");
* n = myecho("bar");
*
* you now can use:
*
* ap_hook_call_lookup(&vp, "foo");
* ap_hook_call_echo(&n, "bar");
*
* BTW, the return value of ap_hook_call() is TRUE or FALSE. TRUE when
* at least one function call was successful (not always the case even
* for AP_HOOK_TOPMOST: if the only checked function will return FALSE
* this will be returned; the same if hook still is not registered).
* FALSE when all functions returned FALSE or no functions are registered
* at all.
*
* NOTE for DSO modules
*
* If you plan to use this mechanism in DSO modules you SHOULD unregister
* all hooks on module unload phase:
*
* static void unregister_hooks(struct module_struct * m) {
* if (m == &client_module) {
* ap_hook_configure_lookup();
* ap_hook_configure_echo();
* }
* }
*
* static void unregister_hooks(struct module_struct * m) {
* if (m == &server_module) {
* ap_hook_unregister_lookup(mylookup);
* ap_hook_unregister_echo(myecho);
* }
* }
*
* Insert unregister_hooks function as remove_module hook in module
* structure.
*
* NOTE for modules with multiple source files
*
* It's safe to use ap_hook_define_client and/or ap_hook_define_server
* in .h file included in multiple .c files. But if you have non-gcc
* based compiler this will lead to a lot of duplicated static functions.
* So in this case you should use ap_hook_define_client_global and/or
* ap_hook_define_server_global in .h file. In ONE .c file for each
* module you should use ap_hook_define_client_realize and/or
* ap_hook_define_server_realize to make instances for functions.
* You should include .h file with ap_hook_define_client_global and/or
* ap_hook_define_server_global before ap_hook_define_client_realize
* and/or ap_hook_define_server_realize. Unfortunatelly this usage of
* non-static functions could lead to namespace pollution. To avoid this
* all autogenerated functions will be created with prefix
* ap_hook_module_name instead of just ap_hook (module name is first
* parameter in ap_hook_define_{client,server}_{global,realize} macro).
*
* SPEED ISSUES
*
* This implementation is designed to be VERY fast. For example this
* program (direct function call):
*
* void main(void) {
* FILE *f=fopen("/dev/null","a");
* for (int i=0;i<10000000;i++) fputc(' ',f);
* fclose(f);
* }
*
* works 2.95 seconds on Pentium200MMX (egcs 1.1b with -O6 -mcpu=pentium).
*
* This program (call over hooks):
*
* ap_hook_define(fputc,(int *res,int c,FILE *stream),(res,c,stream));
* int fputc_wrapper(int *res,int c,FILE *stream) {
* *res=fputc(c,stream);
* return TRUE;
* }
*
* void main(void) {
* FILE *f=fopen("/dev/null","a");
* ap_hook_register_fputc(fputc_wrapper);
* ap_hook_configure_fputc(AP_HOOK_NORMAL);
* for (int i=0;i<10000000;i++) {
* int dummy;
* ap_hook_call_fputc(&dummy,' ',f);
* }
* fclose(f);
* }
*
* will work 3.76 seconds on the same Pentium200MMX.
*/
EAPI-2-EAPIk-4-2.1b9-SNAP.patch4.gz