From b33450ff28ab76788730e7a61e146bc97734b1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Thu, 17 Jul 2008 18:04:16 +0200 Subject: [PATCH] Separate module from plugin, add version to server struct. --- src/base.h | 4 ++++ src/module.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/plugin.h | 59 ++++++++++++++++++++++------------------------------ 3 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 src/module.h diff --git a/src/base.h b/src/base.h index 9506b25..e2d7404 100644 --- a/src/base.h +++ b/src/base.h @@ -15,7 +15,11 @@ typedef struct connection connection; #include "actions.h" #include "request.h" +#define SERVER_VERSION ((guint) 0x01FF0000) + struct server { + guint version; + GHashTable *plugins; size_t option_count; diff --git a/src/module.h b/src/module.h new file mode 100644 index 0000000..0a8e3c1 --- /dev/null +++ b/src/module.h @@ -0,0 +1,58 @@ +#ifndef _LIGHTTPD_MODULE_H_ +#define _LIGHTTPD_MODULE_H_ + +#include "settings.h" + +#define MODULE_VERSION ((guint) 0x00000001) +#define MODULE_VERSION_CHECK(mods) do { \ + if (mods->version != MODULE_VERSION) { \ + ERROR("Version mismatch for modules system: is %u, expected %u", mods->version, MODULE_VERSION); \ + return FALSE; \ + } } while(0) + +/** see module_load */ +#define MODULE_DEPENDS(mods, name) do { \ + if (!modules_load(mods, name)) { \ + ERROR("Couldn't load dependency '%s'", name); \ + return FALSE; \ + } } while(0) + +struct module; +typedef struct module module; + +struct modules; +typedef struct modules modules; + +/** Type of plugin_init function in modules */ +typedef gboolean (*ModuleInit)(modules *mods, module *mod); +typedef gboolean (*ModuleFree)(modules *mods, module *mod); + +struct module { + gint refcount; /**< count how often module is used. module gets unloaded if refcount reaches zero. */ + gchar *name; /**< name of module, can be set my plugin_init */ + GModule *module; /**< glib handle */ + + gpointer config; /**< private module data */ + ModuleFree free; /**< if set by plugin_init it gets called before module is unloaded */ +}; + +struct modules { + guint version; /**< api version */ + + GHashTable *mods; /**< hash table of modules */ + gpointer main; /**< pointer to a application specific main structure, e.g. server */ +}; + +LI_API modules* modules_init(gpointer main); + +/** Loads a module if not loaded yet and returns the module struct for it (after increasing refcount) + * returns NULL if it couldn't load the module. + * + * You should release modules after you used them with module_release or module_release_name */ +LI_API module* module_load(modules *mods, const gchar* name); + +LI_API void module_acquire(module *mod); +LI_API void module_release(modules *mods, module *module); +LI_API void module_release_name(modules *mods, const char* name); + +#endif diff --git a/src/plugin.h b/src/plugin.h index 0931557..030a216 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -4,8 +4,8 @@ struct plugin; typedef struct plugin plugin; -struct module_option; -typedef struct module_option module_option; +struct plugin_option; +typedef struct plugin_option plugin_option; struct server_option; typedef struct server_option server_option; @@ -19,60 +19,51 @@ typedef struct server_option server_option; #include "base.h" #include "options.h" +#include "module.h" -typedef void (*ModuleInit) (server *srv, plugin *p); -typedef void (*ModuleFree) (server *srv, plugin *p); -typedef gboolean (*ModuleParseOption) (server *srv, gpointer p_d, size_t ndx, option *opt, gpointer *value); -typedef void (*ModuleFreeOption) (server *srv, gpointer p_d, size_t ndx, gpointer value); - -struct module { - GString *name; - - GModule *lib; -}; - +typedef void (*PluginInit) (server *srv, plugin *p); +typedef void (*PluginFree) (server *srv, plugin *p); +typedef gboolean (*PluginParseOption) (server *srv, gpointer p_d, size_t ndx, option *opt, gpointer *value); +typedef void (*PluginFreeOption) (server *srv, gpointer p_d, size_t ndx, gpointer value); struct plugin { size_t version; + const char *name; /**< name of the plugin */ - GString *name; /* name of the plugin */ + gpointer data; /**< private plugin data */ - gpointer data; + PluginFree *free; /**< called before plugin is unloaded */ - ModuleFree *free; - - module_option *options; + plugin_option *options; }; -struct module_option { - const char *key; +struct plugin_option { + const gchar *key; option_type type; - ModuleParseOption parse_option; - ModuleFreeOption free_option; + PluginParseOption parse_option; + PluginFreeOption free_option; }; struct server_option { plugin *p; - /* the plugin must free the _content_ of the option - * opt is zero to get the global default value if nothing is specified - * save result in value - * - * Default behaviour (NULL) is to just use the option as value - */ - ModuleParseOption parse_option; - ModuleFreeOption free_option; + /** the plugin must free the _content_ of the option + * opt is zero to get the global default value if nothing is specified + * save result in value + * + * Default behaviour (NULL) is to just use the option as value + */ + PluginParseOption parse_option; + PluginFreeOption free_option; size_t index, module_index; option_type type; }; -LI_API gboolean plugin_register(server *srv, ModuleInit *init); +LI_API gboolean plugin_register(server *srv, const gchar *name, PluginInit *init); LI_API gboolean parse_option(server *srv, const char *key, option *opt, option_set *mark); -LI_API void release_option(server *srv, option_set *mark); /** Does not free the option_set memory */ - -LI_API gboolean plugin_load(server *srv, const char *module); +LI_API void release_option(server *srv, option_set *mark); /**< Does not free the option_set memory */ #endif