1.. highlight:: c 2 3Hooks 4===== 5 6Libfrr provides type-safe subscribable hook points where other pieces of 7code can add one or more callback functions. "type-safe" in this case 8applies to the function pointers used for subscriptions. The 9implementations checks (at compile-time) whether a callback to be added has 10the appropriate function signature (parameters) for the hook. 11 12Example: 13 14.. code-block:: c 15 :caption: mydaemon.h 16 17 #include "hook.h" 18 DECLARE_HOOK(some_update_event, (struct eventinfo *info), (info)) 19 20.. code-block:: c 21 :caption: mydaemon.c 22 23 #include "mydaemon.h" 24 DEFINE_HOOK(some_update_event, (struct eventinfo *info), (info)) 25 ... 26 hook_call(some_update_event, info); 27 28.. code-block:: c 29 :caption: mymodule.c 30 31 #include "mydaemon.h" 32 static int event_handler(struct eventinfo *info); 33 ... 34 hook_register(some_update_event, event_handler); 35 36Do not use parameter names starting with "hook", these can collide with 37names used by the hook code itself. 38 39 40Return values 41------------- 42 43Callbacks to be placed on hooks always return "int" for now; hook_call will 44sum up the return values from each called function. (The default is 0 if no 45callbacks are registered.) 46 47There are no pre-defined semantics for the value, in most cases it is 48ignored. For success/failure indication, 0 should be success, and 49handlers should make sure to only return 0 or 1 (not -1 or other values). 50 51There is no built-in way to abort executing a chain after a failure of one 52of the callbacks. If this is needed, the hook can use an extra 53``bool *aborted`` argument. 54 55 56Priorities 57---------- 58 59Hooks support a "priority" value for ordering registered calls 60relative to each other. The priority is a signed integer where lower 61values are called earlier. There are also "Koohs", which is hooks with 62reverse priority ordering (for cleanup/deinit hooks, so you can use the 63same priority value). 64 65Recommended priority value ranges are: 66 67======================== =================================================== 68Range Usage 69------------------------ --------------------------------------------------- 70 -999 ... 0 ... 999 main executable / daemon, or library 71 72-1999 ... -1000 modules registering calls that should run before 73 the daemon's bits 74 751000 ... 1999 modules' calls that should run after daemon's 76 (includes default value: 1000) 77======================== =================================================== 78 79Note: the default value is 1000, based on the following 2 expectations: 80 81- most hook_register() usage will be in loadable modules 82- usage of hook_register() in the daemon itself may need relative ordering 83 to itself, making an explicit value the expected case 84 85The priority value is passed as extra argument on hook_register_prio() / 86hook_register_arg_prio(). Whether a hook runs in reverse is determined 87solely by the code defining / calling the hook. (DECLARE_KOOH is actually 88the same thing as DECLARE_HOOK, it's just there to make it obvious.) 89 90 91Definition 92---------- 93 94.. c:macro:: DECLARE_HOOK(name, arglist, passlist) 95.. c:macro:: DECLARE_KOOH(name, arglist, passlist) 96 97 :param name: Name of the hook to be defined 98 :param arglist: Function definition style parameter list in braces. 99 :param passlist: List of the same parameters without their types. 100 101 Note: the second and third macro args must be the hook function's 102 parameter list, with the same names for each parameter. The second 103 macro arg is with types (used for defining things), the third arg is 104 just the names (used for passing along parameters). 105 106 This macro must be placed in a header file; this header file must be 107 included to register a callback on the hook. 108 109 Examples: 110 111 .. code-block:: c 112 113 DECLARE_HOOK(foo, (), ()) 114 DECLARE_HOOK(bar, (int arg), (arg)) 115 DECLARE_HOOK(baz, (const void *x, in_addr_t y), (x, y)) 116 117.. c:macro:: DEFINE_HOOK(name, arglist, passlist) 118 119 Implements an hook. Each ``DECLARE_HOOK`` must have be accompanied by 120 exactly one ``DEFINE_HOOK``, which needs to be placed in a source file. 121 **The hook can only be called from this source file.** This is intentional 122 to avoid overloading and/or misusing hooks for distinct purposes. 123 124 The compiled source file will include a global symbol with the name of the 125 hook prefixed by `_hook_`. Trying to register a callback for a hook that 126 doesn't exist will therefore result in a linker error, or a module 127 load-time error for dynamic modules. 128 129.. c:macro:: DEFINE_KOOH(name, arglist, passlist) 130 131 Same as ``DEFINE_HOOK``, but the sense of priorities / order of callbacks 132 is reversed. This should be used for cleanup hooks. 133 134.. c:function:: int hook_call(name, ...) 135 136 Calls the specified named hook. Parameters to the hook are passed right 137 after the hook name, e.g.: 138 139 .. code-block:: c 140 141 hook_call(foo); 142 hook_call(bar, 0); 143 hook_call(baz, NULL, INADDR_ANY); 144 145 Returns the sum of return values from all callbacks. The ``DEFINE_HOOK`` 146 statement for the hook must be placed in the file before any ``hook_call`` 147 use of the hook. 148 149 150Callback registration 151--------------------- 152 153.. c:function:: void hook_register(name, int (*callback)(...)) 154.. c:function:: void hook_register_prio(name, int priority, int (*callback)(...)) 155.. c:function:: void hook_register_arg(name, int (*callback)(void *arg, ...), void *arg) 156.. c:function:: void hook_register_arg_prio(name, int priority, int (*callback)(void *arg, ...), void *arg) 157 158 Register a callback with an hook. If the caller needs to pass an extra 159 argument to the callback, the _arg variant can be used and the extra 160 parameter will be passed as first argument to the callback. There is no 161 typechecking for this argument. 162 163 The priority value is used as described above. The variants without a 164 priority parameter use 1000 as priority value. 165 166.. c:function:: void hook_unregister(name, int (*callback)(...)) 167.. c:function:: void hook_unregister_arg(name, int (*callback)(void *arg, ...), void *arg) 168 169 Removes a previously registered callback from a hook. Note that there 170 is no _prio variant of these calls. The priority value is only used during 171 registration. 172