]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
module: document the API and simplify the code
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 20 Jan 2017 17:43:01 +0000 (18:43 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 26 Jan 2017 15:20:32 +0000 (16:20 +0100)
This does NOT change the module API/ABI in any way.

daemon/engine.c
lib/module.c
lib/module.h
lib/utils.c

index 9b53b1bc981918befdd530f8e8eb8cd164c46782..fac7c86b82ede343bbc551c60cd7c98545d8698c 100644 (file)
@@ -761,15 +761,20 @@ void engine_stop(struct engine *engine)
        uv_stop(uv_default_loop());
 }
 
-/** Register module properties in Lua environment */
+/** Register module properties in Lua environment, if any. */
 static int register_properties(struct engine *engine, struct kr_module *module)
 {
+       if (!module->config && !module->props) {
+               return kr_ok();
+       }
        lua_newtable(engine->L);
        if (module->config != NULL) {
                REGISTER_MODULE_CALL(engine->L, module, module->config, "config");
        }
-       for (struct kr_prop *p = module->props; p && p->name; ++p) {
-               if (p->cb != NULL && p->name != NULL) {
+
+       const struct kr_prop *p = module->props == NULL ? NULL : module->props();
+       for (; p && p->name; ++p) {
+               if (p->cb != NULL) {
                        REGISTER_MODULE_CALL(engine->L, module, p->cb, p->name);
                }
        }
@@ -855,12 +860,7 @@ int engine_register(struct engine *engine, const char *name, const char *precede
                }
        }
 
-       /* Register properties */
-       if (module->props || module->config) {
-               return register_properties(engine, module);
-       }
-
-       return kr_ok();
+       return register_properties(engine, module);
 }
 
 int engine_unregister(struct engine *engine, const char *name)
index 68c7928ff7f3d74ccb68d8fc62261a3756e97271..6cd46236580688aff7f319d81c7c1437d876bc09 100644 (file)
@@ -44,30 +44,6 @@ static const struct kr_module embedded_modules[] = {
  #define LIBEXT ".so"
 #endif
 
-/** Check ABI version, return error on mismatch. */
-#define ABI_CHECK(m, prefix, symname, required) do { \
-       module_api_cb *_api = NULL; \
-       *(void **) (&_api) = load_symbol((m)->lib, (prefix), (symname)); \
-       if (_api == NULL) { \
-               return kr_error(ENOENT); \
-       } \
-       if (_api() != (required)) { \
-               return kr_error(ENOTSUP); \
-       } \
-} while (0)
-
-/** Load ABI by symbol names. */
-#define ABI_LOAD(m, prefix, s_init, s_deinit, s_config, s_layer, s_prop) do { \
-       module_prop_cb *module_prop = NULL; \
-       *(void **) (&(m)->init)   = load_symbol((m)->lib, (prefix), (s_init)); \
-       *(void **) (&(m)->deinit) = load_symbol((m)->lib, (prefix), (s_deinit)); \
-       *(void **) (&(m)->config) = load_symbol((m)->lib, (prefix), (s_config)); \
-       *(void **) (&(m)->layer)  = load_symbol((m)->lib, (prefix), (s_layer)); \
-       *(void **) (&module_prop) = load_symbol((m)->lib, (prefix), (s_prop)); \
-       if (module_prop != NULL) { \
-               (m)->props = module_prop(); \
-       } \
-} while(0)
 
 /** Load prefixed symbol. */
 static void *load_symbol(void *lib, const char *prefix, const char *name)
@@ -115,9 +91,27 @@ static int load_sym_c(struct kr_module *module, uint32_t api_required)
                }
        }
        /* Load dynamic library module */
-       auto_free char *module_prefix = kr_strcatdup(2, module->name, "_");
-       ABI_CHECK(module, module_prefix, "api", api_required);
-       ABI_LOAD(module, module_prefix, "init", "deinit", "config", "layer", "props");
+       auto_free char *m_prefix = kr_strcatdup(2, module->name, "_");
+
+       /* Check ABI version, return error on mismatch. */
+       module_api_cb *api = load_symbol(module->lib, m_prefix, "api");
+       if (api == NULL) {
+               return kr_error(ENOENT);
+       }
+       if (api() != api_required) {
+               return kr_error(ENOTSUP);
+       }
+
+       /* Load ABI by symbol names. */
+       #define ML(symname) module->symname = \
+               load_symbol(module->lib, m_prefix, #symname)
+       ML(init);
+       ML(deinit);
+       ML(config);
+       ML(layer);
+       ML(props);
+       #undef ML
+
        return kr_ok();
 }
 
index b5e29a78051904d71e2e6bfb99e0aa73b2013494..98a857baaedf07865f27d47f0b75af870355d9aa 100644 (file)
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+/** @file module API definition and functions for (un)loading modules. */
+
 #pragma once
 
 #include "lib/defines.h"
 #include "lib/utils.h"
 #include "lib/layer.h"
 
-/*
- * Forward decls
- */
 struct kr_module;
 struct kr_prop;
 
-/*
- * API definition.
- * @cond internal
+
+/**
+ * Export module API version (place this at the end of your module).
+ *
+ * @param module module name (f.e. hints)
  */
-typedef uint32_t (module_api_cb)(void);
-typedef int (module_init_cb)(struct kr_module *);
-typedef int (module_deinit_cb)(struct kr_module *);
-typedef int (module_config_cb)(struct kr_module *, const char *);
-typedef const kr_layer_api_t* (module_layer_cb)(struct kr_module *);
-typedef struct kr_prop *(module_prop_cb)(void);
-typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
+#define KR_MODULE_EXPORT(module) \
+    KR_EXPORT uint32_t module ## _api() { return KR_MODULE_API; }
 #define KR_MODULE_API ((uint32_t) 0x20161108)
-/* @endcond */
+
+typedef uint32_t (module_api_cb)(void);
+
 
 /**
- * Module property (named callable).
- * A module property has a free-form JSON output (and optional input).
+ * Module representation.
+ *
+ * The five symbols (init, ...) may be defined by the module as name_init(), etc;
+ * all are optional and missing symbols are represented as NULLs;
  */
-struct kr_prop {
-    kr_prop_cb *cb;
-    const char *name;
-    const char *info;
+struct kr_module {
+       char *name;
+
+       /** Constructor.  Called after loading the module.  @return error code. */
+       int (*init)(struct kr_module *self);
+       /** Destructor.  Called before unloading the module.  @return error code. */
+       int (*deinit)(struct kr_module *self);
+       /** Configure with encoded JSON (NULL if missing).  @return error code. */
+       int (*config)(struct kr_module *self, const char *input);
+       /** Get a pointer to packet processing API specs.  See docs on that type. */
+       const kr_layer_api_t * (*layer)(struct kr_module *self);
+       /** Get a pointer to list of properties, terminated by { NULL, NULL, NULL }. */
+       const struct kr_prop * (*props)(void);
+
+       void *lib;      /**< Shared library handle or RTLD_DEFAULT */
+       void *data;     /**< Custom data context. */
 };
 
 /**
- * Module representation.
+ * Module property callback.  Input and output is passed via a JSON encoded in a string.
+ *
+ * @param env pointer to the lua engine, i.e. struct engine *env (TODO: explicit type)
+ * @param input parameter (NULL if missing/nil on lua level)
+ * @return a free-form JSON output (malloc-ated)
  */
-struct kr_module {
-    char *name;               /**< Name. */
-    module_init_cb   *init;   /**< Constructor */
-    module_deinit_cb *deinit; /**< Destructor */
   module_config_cb *config; /**< Configuration */
-    module_layer_cb  *layer;  /**< Layer getter */
-    struct kr_prop   *props;  /**< Properties */
-    void *lib;                /**< Shared library handle or RTLD_DEFAULT */
-    void *data;               /**< Custom data context. */
+typedef char *(kr_prop_cb)(void *env, struct kr_module *self, const char *input);
+
+/**
+ * Module property (named callable).
+ */
+struct kr_prop {
+       kr_prop_cb *cb;
+       const char *name;
+       const char *info;
 };
 
+
 /**
  * Load module instance into memory.
  *
@@ -83,10 +100,3 @@ int kr_module_load(struct kr_module *module, const char *name, const char *path)
 KR_EXPORT
 void kr_module_unload(struct kr_module *module);
 
-/**
- * Export module API version (place this at the end of your module).
- *
- * @param module module name (f.e. hints)
- */
-#define KR_MODULE_EXPORT(module) \
-    KR_EXPORT uint32_t module ## _api() { return KR_MODULE_API; }
index 794119ebb469014d52fc94813ca61faf17896f91..ef03987705bf178a4eef67b7ecaad7328d2b7ba4 100644 (file)
@@ -480,10 +480,10 @@ int kr_ranked_rrarray_set_wire(ranked_rr_array_t *array, bool to_wire, uint32_t
 
 static char *callprop(struct kr_module *module, const char *prop, const char *input, void *env)
 {
-       if (!module || !prop) {
+       if (!module || !module->props || !prop) {
                return NULL;
        }
-       for (struct kr_prop *p = module->props; p && p->name; ++p) {
+       for (const struct kr_prop *p = module->props(); p && p->name; ++p) {
                if (p->cb != NULL && strcmp(p->name, prop) == 0) {
                        return p->cb(env, module, input);
                }