]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/hook.h
*: require semicolon after DEFINE_HOOK & co.
[mirror_frr.git] / lib / hook.h
index f7fb7b8a5cf619b14f64a8da2d33872371f7447b..ff3ef29fa3f25c09352a364eee4c04e024eab323 100644 (file)
@@ -35,10 +35,10 @@ extern "C" {
  *
  *   mydaemon.h:
  *     #include "hook.h"
- *     DECLARE_HOOK (some_update_event, (struct eventinfo *info), (info))
+ *     DECLARE_HOOK (some_update_event, (struct eventinfo *info), (info));
  *
  *   mydaemon.c:
- *     DEFINE_HOOK (some_update_event, (struct eventinfo *info), (info))
+ *     DEFINE_HOOK (some_update_event, (struct eventinfo *info), (info));
  *     ...
  *     hook_call (some_update_event, info)
  *
@@ -114,7 +114,9 @@ struct hookent {
        struct hookent *next;
        void *hookfn; /* actually a function pointer */
        void *hookarg;
-       bool has_arg;
+       bool has_arg : 1;
+       bool ent_on_heap : 1;
+       bool ent_used : 1;
        int priority;
        struct frrmod_runtime *module;
        const char *fnname;
@@ -133,21 +135,33 @@ struct hook {
  * always use hook_register(), which uses the static inline helper from
  * DECLARE_HOOK in order to get type safety
  */
-extern void _hook_register(struct hook *hook, void *funcptr, void *arg,
-                          bool has_arg, struct frrmod_runtime *module,
+extern void _hook_register(struct hook *hook, struct hookent *stackent,
+                          void *funcptr, void *arg, bool has_arg,
+                          struct frrmod_runtime *module,
                           const char *funcname, int priority);
+
+/* most hook_register calls are not in a loop or similar and can use a
+ * statically allocated "struct hookent" from the data segment
+ */
+#define _hook_reg_svar(hook, funcptr, arg, has_arg, module, funcname, prio)    \
+       do {                                                                   \
+               static struct hookent stack_hookent = {};                      \
+               _hook_register(hook, &stack_hookent, funcptr, arg, has_arg,    \
+                              module, funcname, prio);                        \
+       } while (0)
+
 #define hook_register(hookname, func)                                          \
-       _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func),    \
+       _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func),    \
                       NULL, false, THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY)
 #define hook_register_arg(hookname, func, arg)                                 \
-       _hook_register(&_hook_##hookname,                                      \
+       _hook_reg_svar(&_hook_##hookname,                                      \
                       _hook_typecheck_arg_##hookname(func), arg, true,        \
                       THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY)
 #define hook_register_prio(hookname, prio, func)                               \
-       _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func),    \
+       _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func),    \
                       NULL, false, THIS_MODULE, #func, prio)
 #define hook_register_arg_prio(hookname, prio, func, arg)                      \
-       _hook_register(&_hook_##hookname,                                      \
+       _hook_reg_svar(&_hook_##hookname,                                      \
                       _hook_typecheck_arg_##hookname(func), arg, true,        \
                       THIS_MODULE, #func, prio)
 
@@ -170,7 +184,7 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
 #define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__)
 
 /* use in header file - declares the hook and its arguments
- * usage:  DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2))
+ * usage:  DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2));
  * as above, "passlist" must use the same order and same names as "arglist"
  *
  * theoretically passlist is not neccessary, but let's keep things simple and
@@ -187,7 +201,9 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
                int(*funcptr) HOOK_ADDDEF arglist)                             \
        {                                                                      \
                return (void *)funcptr;                                        \
-       }
+       }                                                                      \
+       MACRO_REQUIRE_SEMICOLON() /* end */
+
 #define DECLARE_KOOH(hookname, arglist, passlist)                              \
        DECLARE_HOOK(hookname, arglist, passlist)
 
@@ -216,7 +232,8 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
                                hooksum += hookp.farg HOOK_ADDARG passlist;    \
                }                                                              \
                return hooksum;                                                \
-       }
+       }                                                                      \
+       MACRO_REQUIRE_SEMICOLON() /* end */
 
 #define DEFINE_HOOK(hookname, arglist, passlist)                               \
        DEFINE_HOOK_INT(hookname, arglist, passlist, false)