[PATCH 1/3] change plugin interface to be more efficient

Rob Taylor rob.taylor at codethink.co.uk
Tue Jul 31 17:01:16 PDT 2007


This patch converts the plugin interface to use static dats for interested, requires, provides, suggests and prevents. It defines a set of macros for plugin authors to use to make declaring these nice and simple.

It also changes OhmPluginInfo to OhmPluginDesc, cutting down the functions a plugin author needs to export to initialize, destroy and notify - of course, all optional.

As the keys are all now const data, this cuts down strcpys dramitically so memory use and fragmentation should be better.
---
 ohmd/ohm-conf.c   |    2 +-
 ohmd/ohm-module.c |  217 ++++++++++++++++++++++++++--------------------------
 ohmd/ohm-plugin.c |  222 +++++++++++++----------------------------------------
 ohmd/ohm-plugin.h |  134 +++++++++++++++++++++------------
 4 files changed, 248 insertions(+), 327 deletions(-)

diff --git a/ohmd/ohm-conf.c b/ohmd/ohm-conf.c
index df982aa..a231c62 100644
--- a/ohmd/ohm-conf.c
+++ b/ohmd/ohm-conf.c
@@ -262,7 +262,7 @@ ohm_conf_add_key (OhmConf     *conf,
 
 	/* add as the strdup'd value as key is constant */
 	confkey = ohm_confobj_get_key (confobj);
-	g_hash_table_insert (conf->priv->keys, (gpointer) confkey, (gpointer) confobj);
+	g_hash_table_insert (conf->priv->keys, (gpointer) g_strdup(confkey), (gpointer) confobj);
 
 	return TRUE;
 }
diff --git a/ohmd/ohm-module.c b/ohmd/ohm-module.c
index 182a025..cadf8e6 100644
--- a/ohmd/ohm-module.c
+++ b/ohmd/ohm-module.c
@@ -53,19 +53,32 @@ struct OhmModulePrivate
 	GSList			*plugins;	/* list of loaded OhmPlugin's */
 	GHashTable		*interested;
 	OhmConf			*conf;
-	gboolean		 doing_preload;
 	gboolean		 do_extra_checks;
+	gchar			**modules_banned;
+	gchar			**modules_suggested;
+	gchar			**modules_required;
 };
 
 /* used as a hash entry type to provide int-passing services to the plugin */
 typedef struct {
 	OhmPlugin		*plugin;
 	gint			 id;
-} OhmModuleNofif;
+} OhmModuleNotify;
 
 G_DEFINE_TYPE (OhmModule, ohm_module, G_TYPE_OBJECT)
 
 static void
+free_notify_list (GList *list)
+{
+	GList *l;
+
+	for (l=list; l != NULL; l=l->next) {
+		g_slice_free (OhmModuleNotify, list->data);
+	}
+	g_list_free (list);
+}
+
+static void
 key_changed_cb (OhmConf     *conf,
 		const gchar *key,
 		gint	     value,
@@ -73,7 +86,7 @@ key_changed_cb (OhmConf     *conf,
 {
 	GSList **entry;
 	GSList *l;
-	OhmModuleNofif *notif;
+	OhmModuleNotify *notif;
 	const gchar *name;
 
 	ohm_debug ("key changed! %s : %i", key, value);
@@ -89,110 +102,109 @@ key_changed_cb (OhmConf     *conf,
 	ohm_debug ("found watched key %s", key);
 	/* go thru the SList and notify each plugin */
 	for (l=*entry; l != NULL; l=l->next) {
-		notif = (OhmModuleNofif *) l->data;
+		notif = (OhmModuleNotify *) l->data;
 		name = ohm_plugin_get_name (notif->plugin);
 		ohm_debug ("notify %s with id:%i", name, notif->id);
-		ohm_plugin_conf_notify (notif->plugin, notif->id, value);
+		ohm_plugin_notify (notif->plugin, notif->id, value);
 	}
 }
 
 static void
-add_interested_cb (OhmPlugin   *plugin,
-		   const gchar *key,
-		   gint	        id,
-		   OhmModule   *module)
+add_interesteds (OhmModule   *module, OhmPlugin   *plugin)
 {
 	GSList **entry;
 	GSList **l;
-	OhmModuleNofif *notif;
-	ohm_debug ("add interested! %s : %i", key, id);
+	OhmModuleNotify *notif;
+	const OhmPluginKeyIdMap *interested;
+	
+	if (!plugin->interested)
+		return;
 
-	/* if present, add to SList, if not, add to hash as slist object */
-	entry = g_hash_table_lookup (module->priv->interested, key);
+	for (interested = plugin->interested; interested->key_name; interested++) {
+		ohm_debug ("add interested! %s : %i", interested->key_name, interested->local_key_id);
 
-	/* create a new notifier, and copy over the data */
-	notif = g_new0 (OhmModuleNofif, 1); /* TODO: use gslice */
-	notif->plugin = plugin;
-	notif->id = id;
+		/* if present, add to SList, if not, add to hash as slist object */
+		entry = g_hash_table_lookup (module->priv->interested, interested->key_name);
 
-	if (entry != NULL) {
-		/* already present, just append to SList */
-		ohm_debug ("key already watched by someting else");
-		*entry = g_slist_prepend (*entry, (gpointer) notif);
-	} else {
-		ohm_debug ("key not already watched by something else");
-		/* create the new SList andd add the new notification to it */
-		l = g_new0 (GSList *, 1);
-		*l = NULL;
-		*l = g_slist_prepend (*l, (gpointer) notif);
-		/* fixme we need to free this g_strdup at finalize and clear the list */
-		g_hash_table_insert (module->priv->interested, (gpointer) g_strdup (key), l);
-	}
-}
+		/* create a new notifier, and copy over the data */
+		notif = g_slice_new (OhmModuleNotify);
+		notif->plugin = plugin;
+		notif->id = interested->local_key_id;
 
-static void
-add_require_cb (OhmPlugin   *plugin,
-		const gchar *name,
-		OhmModule   *module)
-{
-	if (module->priv->doing_preload == FALSE) {
-		g_error ("modules not allowed to call ohm_plugin_require() after load()");
+		if (entry != NULL) {
+			/* already present, just append to SList */
+			ohm_debug ("key already watched by someting else");
+			*entry = g_slist_prepend (*entry, (gpointer) notif);
+		} else {
+			ohm_debug ("key not already watched by something else");
+			/* create the new SList andd add the new notification to it */
+			l = g_new0 (GSList *, 1);
+			*l = NULL;
+			*l = g_slist_prepend (*l, (gpointer) notif);
+			/*dupping string to cope if module is removed*/
+			g_hash_table_insert (module->priv->interested, (gpointer) interested->key_name, l);
+		}
 	}
-	ohm_debug ("adding module require %s", name);
-	module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup (name));
 }
 
-static void
-add_suggest_cb (OhmPlugin   *plugin,
-		const gchar *name,
-		OhmModule   *module)
+
+static gboolean
+add_provides (OhmModule *module, OhmPlugin *plugin)
 {
-	if (module->priv->doing_preload == FALSE) {
-		g_error ("modules not allowed to call ohm_suggest_require() after load()");
+	GError *error;
+	const char **provides = plugin->provides;
+	gboolean ret=TRUE;
+	error = NULL;
+
+	if (!provides)
+		return TRUE;
+
+	for (; *provides; provides++) {
+		ohm_debug ("%s provides %s", ohm_plugin_get_name(plugin), *provides);
+		/* provides keys are never public and are always preset at zero */
+		ret &= ohm_conf_add_key (module->priv->conf, *provides, 0, FALSE, &error);
+		if (ret == FALSE) {
+			ohm_debug ("Cannot provide key %s: %s", *provides, error->message);
+			g_error_free (error);
+		}
 	}
-	ohm_debug ("adding module suggest %s", name);
-	module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) strdup (name));
+	return ret;
 }
 
 static void
-add_prevent_cb (OhmPlugin   *plugin,
-		const gchar *name,
-		OhmModule   *module)
+add_names (GSList **l, const char **names)
 {
-	if (module->priv->doing_preload == FALSE) {
-		g_error ("modules not allowed to call ohm_plugin_prevent() after load()");
+	if (!names)
+		return;
+
+	for (;*names; names++) {
+		*l = g_slist_prepend (*l, (gpointer) *names);
 	}
-	ohm_debug ("adding module prevent %s", name);
-	module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) strdup (name));
 }
 
 static gboolean
 ohm_module_add_plugin (OhmModule *module, const gchar *name)
 {
 	OhmPlugin *plugin;
-	gboolean ret;
 
 	/* setup new plugin */
 	plugin = ohm_plugin_new ();
-	g_signal_connect (plugin, "add-interested",
-			  G_CALLBACK (add_interested_cb), module);
-	g_signal_connect (plugin, "add-require",
-			  G_CALLBACK (add_require_cb), module);
-	g_signal_connect (plugin, "add-suggest",
-			  G_CALLBACK (add_suggest_cb), module);
-	g_signal_connect (plugin, "add-prevent",
-			  G_CALLBACK (add_prevent_cb), module);
-	/* try to preload plugin, this might fail */
-	ret = ohm_plugin_preload (plugin, name);
-	if (ret == TRUE) {
-		ohm_debug ("adding %s to module list", name);
-		module->priv->plugins = g_slist_prepend (module->priv->plugins, (gpointer) plugin);
-	} else {
-		/* if it does, just unref and warn */
-		ohm_debug ("not adding %s to module list as cannot load", name);
-		g_object_unref (plugin);
-	}
-	return ret;
+
+	/* try to load plugin, this might fail */
+	if (!ohm_plugin_load (plugin, name))
+		return FALSE;
+
+	ohm_debug ("adding %s to module list", name);
+	module->priv->plugins = g_slist_prepend (module->priv->plugins, (gpointer) plugin);
+	add_names (&module->priv->mod_require, plugin->requires);
+	add_names (&module->priv->mod_suggest, plugin->suggests);
+	add_names (&module->priv->mod_prevent, plugin->prevents);
+	add_interesteds (module, plugin);
+
+	if (!add_provides (module, plugin))
+		return FALSE;
+	else
+		return TRUE;
 }
 
 /* adds plugins from require and suggests lists. Failure of require is error, failure of suggests is warning */
@@ -281,7 +293,6 @@ ohm_module_read_defaults (OhmModule *module)
 	GKeyFile *keyfile;
 	gchar *filename;
 	gchar *conf_dir;
-	gchar **modules;
 	gsize length;
 	guint i;
 	GError *error;
@@ -305,7 +316,7 @@ ohm_module_read_defaults (OhmModule *module)
 	error = NULL;
 	ret = g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error);
 	if (ret == FALSE) {
-		g_error ("cannot load goddammded keyfile %s", filename);
+		g_error ("cannot load keyfile %s", filename);
 	}
 	g_free (filename);
 
@@ -319,49 +330,43 @@ ohm_module_read_defaults (OhmModule *module)
 
 	/* read and process ModulesBanned */
 	error = NULL;
-	modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesBanned", &length, &error);
+	module->priv->modules_banned = g_key_file_get_string_list (keyfile, "Modules", "ModulesBanned", &length, &error);
 	if (error != NULL) {
 		ohm_debug ("ModulesBanned read error: %s", error->message);
 		g_error_free (error);
 	}
 	for (i=0; i<length; i++) {
-		ohm_debug ("ModulesBanned: %s", modules[i]);
-		module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) strdup(modules[i]));
+		ohm_debug ("ModulesBanned: %s", module->priv->modules_banned[i]);
+		module->priv->mod_prevent = g_slist_prepend (module->priv->mod_prevent, (gpointer) module->priv->modules_banned[i]);
 	}
-	g_strfreev (modules);
 
 	/* read and process ModulesSuggested */
 	error = NULL;
-	modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesSuggested", &length, &error);
+	module->priv->modules_suggested = g_key_file_get_string_list (keyfile, "Modules", "ModulesSuggested", &length, &error);
 	if (error != NULL) {
 		ohm_debug ("ModulesSuggested read error: %s", error->message);
 		g_error_free (error);
 	}
 	for (i=0; i<length; i++) {
-		ohm_debug ("ModulesSuggested: %s", modules[i]);
-		module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) strdup(modules[i]));
+		ohm_debug ("ModulesSuggested: %s", module->priv->modules_suggested[i]);
+		module->priv->mod_suggest = g_slist_prepend (module->priv->mod_suggest, (gpointer) module->priv->modules_suggested[i]);
 	}
-	g_strfreev (modules);
 
 	/* read and process ModulesRequired */
 	error = NULL;
-	modules = g_key_file_get_string_list (keyfile, "Modules", "ModulesRequired", &length, &error);
+	module->priv->modules_required = g_key_file_get_string_list (keyfile, "Modules", "ModulesRequired", &length, &error);
 	if (error != NULL) {
 		ohm_debug ("ModulesRequired read error: %s", error->message);
 		g_error_free (error);
 	}
 	for (i=0; i<length; i++) {
-		ohm_debug ("ModulesRequired: %s", modules[i]);
-		module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup(modules[i]));
+		ohm_debug ("ModulesRequired: %s", module->priv->modules_required[i]);
+		module->priv->mod_require = g_slist_prepend (module->priv->mod_require, (gpointer) strdup(module->priv->modules_required[i]));
 	}
-	g_strfreev (modules);
 
 	g_key_file_free (keyfile);
 }
 
-/**
- * ohm_module_finalize:
- **/
 static void
 ohm_module_finalize (GObject *object)
 {
@@ -412,20 +417,13 @@ ohm_module_init (OhmModule *module)
 	gboolean ret;
 
 	module->priv = OHM_MODULE_GET_PRIVATE (module);
-	/* clear lists */
-	module->priv->mod_require = NULL;
-	module->priv->mod_suggest = NULL;
-	module->priv->mod_prevent = NULL;
-	module->priv->mod_loaded = NULL;
 
-	module->priv->interested = g_hash_table_new (g_str_hash, g_str_equal);
+	module->priv->interested = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)free_notify_list);
 
 	module->priv->conf = ohm_conf_new ();
 	g_signal_connect (module->priv->conf, "key-changed",
 			  G_CALLBACK (key_changed_cb), module);
 
-	module->priv->doing_preload = TRUE;
-
 	/* read the defaults in from modules.ini */
 	ohm_module_read_defaults (module);
 
@@ -438,13 +436,16 @@ ohm_module_init (OhmModule *module)
 		ohm_debug ("module add iteration #%i", i++);
 		ohm_module_add_all_plugins (module);
 		if (i > 10) {
-			g_error ("module add too complex, please file a bug");
+			g_error ("Module add too complex, please file a bug");
 		}
 	}
-	module->priv->doing_preload = FALSE;
+	g_strfreev (module->priv->modules_required);
+	g_strfreev (module->priv->modules_suggested);
+	g_slist_free (module->priv->mod_prevent);
+	g_strfreev (module->priv->modules_banned);
 
-	/* add defaults for each plugin before the coldplug */
-	ohm_debug ("starting plugin coldplug");
+	/* add defaults for each plugin before the initialization*/
+	ohm_debug ("loading plugin defaults");
 	for (l=module->priv->plugins; l != NULL; l=l->next) {
 		plugin = (OhmPlugin *) l->data;
 		name = ohm_plugin_get_name (plugin);
@@ -459,13 +460,13 @@ ohm_module_init (OhmModule *module)
 		}
 	}
 
-	/* coldplug each plugin */
-	ohm_debug ("starting plugin coldplug");
+	/* initialize each plugin */
+	ohm_debug ("starting plugin initialization");
 	for (l=module->priv->plugins; l != NULL; l=l->next) {
 		plugin = (OhmPlugin *) l->data;
 		name = ohm_plugin_get_name (plugin);
-		ohm_debug ("coldplug %s", name);
-		ohm_plugin_coldplug (plugin);
+		ohm_debug ("initialize %s", name);
+		ohm_plugin_initialize (plugin);
 	}
 }
 
diff --git a/ohmd/ohm-plugin.c b/ohmd/ohm-plugin.c
index e292264..5279df3 100644
--- a/ohmd/ohm-plugin.c
+++ b/ohmd/ohm-plugin.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007 Codethink Ltd
+ *            Author: Rob Taylor <rob.taylor at codethink.co.uk>
  *
  * Licensed under the GNU Lesser General Public License Version 2
  *
@@ -50,7 +52,6 @@
 struct OhmPluginPrivate
 {
 	OhmConf			*conf;
-	OhmPluginInfo		*info;
 	GModule			*handle;
 	gchar			*name;
 	/* not assigned unless a plugin uses hal */
@@ -60,64 +61,14 @@ struct OhmPluginPrivate
 	OhmPluginHalCondition	 hal_condition_cb;
 };
 
-enum {
-	ADD_INTERESTED,
-	ADD_REQUIRE,
-	ADD_SUGGEST,
-	ADD_PREVENT,
-	LAST_SIGNAL
-};
-
-static guint	     signals[LAST_SIGNAL] = { 0, };
-
 G_DEFINE_TYPE (OhmPlugin, ohm_plugin, G_TYPE_OBJECT)
 
-/**
- * ohm_plugin_get_key:
- **/
 gboolean
-ohm_plugin_require (OhmPlugin   *plugin,
-		    const gchar *name)
-{
-	ohm_debug ("emitting add-require '%s'", name);
-	g_signal_emit (plugin, signals[ADD_REQUIRE], 0, name);
-	return TRUE;
-}
-
-/**
- * ohm_plugin_add_notify_key:
- **/
-gboolean
-ohm_plugin_suggest (OhmPlugin   *plugin,
-		    const gchar *name)
-{
-	ohm_debug ("emitting add-suggest '%s'", name);
-	g_signal_emit (plugin, signals[ADD_SUGGEST], 0, name);
-	return TRUE;
-}
-
-/**
- * ohm_plugin_set_key:
- *
- **/
-gboolean
-ohm_plugin_prevent (OhmPlugin   *plugin,
-		    const gchar *name)
-{
-	ohm_debug ("emitting add-prevent '%s'", name);
-	g_signal_emit (plugin, signals[ADD_PREVENT], 0, name);
-	return TRUE;
-}
-
-gboolean
-ohm_plugin_preload (OhmPlugin *plugin, const gchar *name)
+ohm_plugin_load (OhmPlugin *plugin, const gchar *name)
 {
 	gchar *path;
 	GModule *handle;
 	gchar *filename;
-	gboolean ret;
-
-	OhmPluginInfo * (*ohm_init_plugin) (OhmPlugin *);
 
 	g_return_val_if_fail (name != NULL, FALSE);
 
@@ -138,23 +89,20 @@ ohm_plugin_preload (OhmPlugin *plugin, const gchar *name)
 	}
 	g_free (path);
 
-	if (!g_module_symbol (handle, "ohm_init_plugin", (gpointer) &ohm_init_plugin)) {
+	if (!g_module_symbol (handle, "ohm_plugin_desc", (gpointer) &plugin->desc)) {
 		g_module_close (handle);
-		g_error ("could not find init function in plugin");
+		ohm_debug ("could not find description in plugin %s, not loading", name);
+		return FALSE;
 	}
 
+	g_module_symbol (handle, "ohm_plugin_interested", (gpointer) &plugin->interested);
+	g_module_symbol (handle, "ohm_plugin_provides", (gpointer) &plugin->provides);
+	g_module_symbol (handle, "ohm_plugin_requires", (gpointer) &plugin->requires);
+	g_module_symbol (handle, "ohm_plugin_suggests", (gpointer) &plugin->suggests);
+	g_module_symbol (handle, "ohm_plugin_prevents", (gpointer) &plugin->prevents);
 	plugin->priv->handle = handle;
 	plugin->priv->name = g_strdup (name);
-	plugin->priv->info = ohm_init_plugin (plugin);
-
-	/* do the load */
-	ret = TRUE;
-	if (plugin->priv->info->preload != NULL) {
-		ret = plugin->priv->info->preload (plugin);
-		/* the plugin preload might fail if we do not have the hardware */
-	}
-
-	return ret;
+	return TRUE;
 }
 
 const gchar *
@@ -170,7 +118,7 @@ ohm_plugin_get_version (OhmPlugin *plugin)
 {
 	g_return_val_if_fail (plugin != NULL, NULL);
 
-	return plugin->priv->info->version;
+	return plugin->desc->version;
 }
 
 const gchar *
@@ -178,32 +126,13 @@ ohm_plugin_get_author (OhmPlugin *plugin)
 {
 	g_return_val_if_fail (plugin != NULL, NULL);
 
-	return plugin->priv->info->author;
+	return plugin->desc->author;
 }
 
-G_MODULE_EXPORT gboolean
-ohm_plugin_conf_provide (OhmPlugin *plugin,
-			 const gchar *name)
-{
-	GError *error;
-	gboolean ret;
-	error = NULL;
-
-	ohm_debug ("%s provides %s", plugin->priv->name, name);
-
-	/* provides keys are never public and are always preset at zero */
-	ret = ohm_conf_add_key (plugin->priv->conf, name, 0, FALSE, &error);
-	if (ret == FALSE) {
-		ohm_debug ("Cannot provide key: %s", error->message);
-		g_error_free (error);
-	}
-	return ret;
-}
-
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_conf_get_key (OhmPlugin   *plugin,
-			 const gchar *key,
-			 int         *value)
+			const gchar  *key,
+			int	     *value)
 {
 	GError *error;
 	gboolean ret;
@@ -216,10 +145,10 @@ ohm_plugin_conf_get_key (OhmPlugin   *plugin,
 	return ret;
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_conf_set_key (OhmPlugin   *plugin,
-			 const gchar *key,
-			 int          value)
+			const gchar  *key,
+			int	      value)
 {
 	GError *error;
 	gboolean ret;
@@ -233,30 +162,31 @@ ohm_plugin_conf_set_key (OhmPlugin   *plugin,
 	return ret;
 }
 
-G_MODULE_EXPORT gboolean
-ohm_plugin_conf_notify (OhmPlugin   *plugin,
-			int          id,
-			int          value)
+gboolean
+ohm_plugin_notify (OhmPlugin   *plugin,
+			int     id,
+			int     value)
 {
-	plugin->priv->info->conf_notify (plugin, id, value);
+	plugin->desc->notify (plugin, id, value);
 	return TRUE;
 }
 
-G_MODULE_EXPORT gboolean
-ohm_plugin_coldplug (OhmPlugin   *plugin)
+gboolean
+ohm_plugin_initialize (OhmPlugin   *plugin)
 {
-	plugin->priv->info->coldplug (plugin);
+	if (plugin->desc->initialize)
+		plugin->desc->initialize (plugin);
 	return TRUE;
 }
 
 /* only use this when required */
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_hal_init (OhmPlugin   *plugin)
 {
 	DBusConnection *conn;
 
 	if (plugin->priv->hal_ctx != NULL) {
-		g_warning ("already initialised HAL from this plugin");
+		g_warning ("already initialized HAL from this plugin");
 		return FALSE;
 	}
 
@@ -347,7 +277,7 @@ hal_condition_cb (LibHalContext *ctx,
 	plugin->priv->hal_condition_cb (plugin, id, name, detail);
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_hal_use_property_modified (OhmPlugin	         *plugin,
 				      OhmPluginHalPropMod func)
 {
@@ -356,7 +286,7 @@ ohm_plugin_hal_use_property_modified (OhmPlugin	         *plugin,
 	return TRUE;
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_hal_use_condition (OhmPlugin	           *plugin,
 			      OhmPluginHalCondition func)
 {
@@ -365,7 +295,7 @@ ohm_plugin_hal_use_condition (OhmPlugin	           *plugin,
 	return TRUE;
 }
 
-G_MODULE_EXPORT guint
+guint
 ohm_plugin_hal_add_device_capability (OhmPlugin   *plugin,
 				      const gchar *capability)
 {
@@ -374,7 +304,7 @@ ohm_plugin_hal_add_device_capability (OhmPlugin   *plugin,
 	guint i;
 
 	if (plugin->priv->hal_ctx == NULL) {
-		g_warning ("HAL not already initialised from this plugin!");
+		g_warning ("HAL not already initialized from this plugin!");
 		return FALSE;
 	}
 
@@ -397,7 +327,7 @@ ohm_plugin_hal_add_device_capability (OhmPlugin   *plugin,
 	return num_devices;
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_hal_get_bool (OhmPlugin   *plugin,
 			 guint        id,
 			 const gchar *key,
@@ -405,7 +335,7 @@ ohm_plugin_hal_get_bool (OhmPlugin   *plugin,
 {
 	const gchar *udi;
 	if (plugin->priv->hal_ctx == NULL) {
-		g_warning ("HAL not already initialised from this plugin!");
+		g_warning ("HAL not already initialized from this plugin!");
 		return FALSE;
 	}
 	
@@ -414,7 +344,7 @@ ohm_plugin_hal_get_bool (OhmPlugin   *plugin,
 	return TRUE;
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_hal_get_int (OhmPlugin   *plugin,
 			guint        id,
 			const gchar *key,
@@ -422,7 +352,7 @@ ohm_plugin_hal_get_int (OhmPlugin   *plugin,
 {
 	const gchar *udi;
 	if (plugin->priv->hal_ctx == NULL) {
-		g_warning ("HAL not already initialised from this plugin!");
+		g_warning ("HAL not already initialized from this plugin!");
 		return FALSE;
 	}
 	udi = ohm_plugin_find_udi_from_id (plugin, id);
@@ -431,7 +361,7 @@ ohm_plugin_hal_get_int (OhmPlugin   *plugin,
 }
 
 /* have to free */
-G_MODULE_EXPORT gchar *
+gchar *
 ohm_plugin_hal_get_udi (OhmPlugin *plugin, guint id)
 {
 	const gchar *udi;
@@ -442,7 +372,7 @@ ohm_plugin_hal_get_udi (OhmPlugin *plugin, guint id)
 	return g_strdup (udi);
 }
 
-G_MODULE_EXPORT gboolean
+gboolean
 ohm_plugin_spawn_async (OhmPlugin   *plugin,
 			const gchar *commandline)
 {
@@ -459,16 +389,6 @@ ohm_plugin_spawn_async (OhmPlugin   *plugin,
 	return ret;
 }
 
-G_MODULE_EXPORT gboolean
-ohm_plugin_conf_interested (OhmPlugin   *plugin,
-			    const gchar	*key,
-			    gint         id)
-{
-	ohm_debug ("%s provides wants notification of %s on signal %i", plugin->priv->name, key, id);
-	g_signal_emit (plugin, signals[ADD_INTERESTED], 0, key, id);
-	return TRUE;
-}
-
 static void
 ohm_plugin_free_hal_table (OhmPlugin *plugin)
 {
@@ -501,18 +421,16 @@ ohm_plugin_finalize (GObject *object)
 
 	g_object_unref (plugin->priv->conf);
 
-	if (plugin->priv->info != NULL) {
-		if (plugin->priv->info->unload != NULL) {
-			plugin->priv->info->unload (plugin);
-			/* free hal stuff, if used */
-			if (plugin->priv->hal_ctx != NULL) {
-				ohm_plugin_free_hal_table (plugin);
-				libhal_ctx_shutdown (plugin->priv->hal_ctx, NULL);
-			}
+	if (plugin->desc != NULL) {
+		if (plugin->desc->destroy != NULL) {
+			plugin->desc->destroy (plugin);
 		}
-	}
-	if (plugin->priv->handle != NULL) {
-		g_module_close (plugin->priv->handle);
+		/* free hal stuff, if used */
+		if (plugin->priv->hal_ctx != NULL) {
+			ohm_plugin_free_hal_table (plugin);
+			libhal_ctx_shutdown (plugin->priv->hal_ctx, NULL);
+		}
+		
 	}
 
 	if (plugin->priv->name != NULL) {
@@ -530,44 +448,8 @@ static void
 ohm_plugin_class_init (OhmPluginClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	object_class->finalize	   = ohm_plugin_finalize;
-
-	signals[ADD_INTERESTED] =
-		g_signal_new ("add-interested",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (OhmPluginClass, add_interested),
-			      NULL, NULL,
-			      ohm_marshal_VOID__STRING_INT,
-			      G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
-
-	signals[ADD_REQUIRE] =
-		g_signal_new ("add-require",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (OhmPluginClass, add_require),
-			      NULL, NULL,
-			      ohm_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
-
-	signals[ADD_SUGGEST] =
-		g_signal_new ("add-suggest",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (OhmPluginClass, add_suggest),
-			      NULL, NULL,
-			      ohm_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
-
-	signals[ADD_PREVENT] =
-		g_signal_new ("add-prevent",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (OhmPluginClass, add_prevent),
-			      NULL, NULL,
-			      ohm_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
 
+	object_class->finalize = ohm_plugin_finalize;
 	g_type_class_add_private (klass, sizeof (OhmPluginPrivate));
 }
 
@@ -579,7 +461,6 @@ ohm_plugin_init (OhmPlugin *plugin)
 {
 	plugin->priv = OHM_PLUGIN_GET_PRIVATE (plugin);
 
-	plugin->priv->conf = ohm_conf_new ();
 	plugin->priv->hal_udis = g_ptr_array_new ();
 }
 
@@ -591,5 +472,6 @@ ohm_plugin_new (void)
 {
 	OhmPlugin *plugin;
 	plugin = g_object_new (OHM_TYPE_PLUGIN, NULL);
+	plugin->priv->conf = ohm_conf_new ();
 	return OHM_PLUGIN (plugin);
 }
diff --git a/ohmd/ohm-plugin.h b/ohmd/ohm-plugin.h
index 2c13250..e9871f4 100644
--- a/ohmd/ohm-plugin.h
+++ b/ohmd/ohm-plugin.h
@@ -33,61 +33,104 @@ G_BEGIN_DECLS
 #define OHM_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), OHM_TYPE_PLUGIN, OhmPluginClass))
 
 typedef struct OhmPluginPrivate OhmPluginPrivate;
+typedef struct OhmPlugin OhmPlugin;
+typedef struct OhmPluginDesc OhmPluginDesc;
+typedef struct OhmPluginClass OhmPluginClass;
+typedef struct OhmPluginKeyIdMap OhmPluginKeyIdMap;
 
-typedef struct
+struct OhmPlugin
 {
-	GObject		  parent;
+	GObject		 parent;
+	const OhmPluginDesc *desc;
+	const OhmPluginKeyIdMap *interested;
+	const char **provides;
+	const char **requires;
+	const char **suggests;
+	const char **prevents;
 	OhmPluginPrivate *priv;
-} OhmPlugin;
+};
 
-typedef struct
+struct OhmPluginClass
 {
 	GObjectClass	parent_class;
-	void		(* add_interested)		(OhmPlugin	*plugin,
-							 const gchar	*key,
-							 gint		 id);
-	void		(* add_require)			(OhmPlugin	*plugin,
-							 const gchar	*name);
-	void		(* add_suggest)			(OhmPlugin	*plugin,
-							 const gchar	*name);
-	void		(* add_prevent)			(OhmPlugin	*plugin,
-							 const gchar	*name);
-	void		(* hal_key_changed)		(OhmPlugin	*plugin,
-							 const gchar	*key);
-} OhmPluginClass;
-
-typedef struct {
-	gchar		*description;
-	gchar		*version;
-	gchar		*author;
-	gboolean	(*preload)			(OhmPlugin *plugin);
-	void		(*unload)			(OhmPlugin *plugin);
-	void		(*coldplug)			(OhmPlugin *plugin);
-	void		(*conf_notify)			(OhmPlugin *plugin, gint id, gint value);
-} OhmPluginInfo;
-
-typedef void (*OhmPluginHalPropMod) 			(OhmPlugin	*plugin,
+};
+
+struct OhmPluginKeyIdMap {
+	const char	*key_name;
+	gint		local_key_id;
+};
+
+typedef enum {
+	OHM_LICENSE_LGPL,
+	OHM_LICENSE_GPL,
+	OHM_LICENSE_MIT,
+	OHM_LICENSE_BSD,
+	OHM_LICENSE_NON_FREE,
+	OHM_LICENSE_FREE_OTHER
+} OhmLicenseType;
+
+/**
+ * OhmPluginDesc:
+ * @description: Plugin description
+ * @version: Plugin version
+ * @author: Plugin author
+ * @license: Plugin license type
+ * @initialize: method to call on plugin initialization
+ * @destroy: method to call on plugin destruction
+ * @notify: method to call to notify of key changes, using the id's described by
+ *          #OHM_PLUGIN_INTERESTED
+ * @padding: Padding for future expansion
+ */
+struct OhmPluginDesc {
+	const char		*description;
+	const char		*version;
+	const char		*author;
+	OhmLicenseType	license;
+	void		(*initialize)			(OhmPlugin *plugin);
+	void		(*destroy)			(OhmPlugin *plugin);
+	void		(*notify)			(OhmPlugin *plugin, gint id, gint value);
+	gpointer padding[8];
+};
+
+#define OHM_PLUGIN_DESCRIPTION(description, version, author, license, initialize, destroy, notify) \
+	G_MODULE_EXPORT const OhmPluginDesc ohm_plugin_desc = { \
+		description, \
+		version, \
+		author, \
+		license,\
+		initialize, \
+		destroy, \
+		notify, \
+		{0} \
+	}
+
+#define OHM_PLUGIN_INTERESTED(...) \
+	G_MODULE_EXPORT const OhmPluginKeyIdMap ohm_plugin_interested[] = {__VA_ARGS__, {NULL,0}}
+
+#define OHM_PLUGIN_PROVIDES(...) \
+	G_MODULE_EXPORT const gchar *ohm_plugin_provides[] = {__VA_ARGS__,NULL}
+
+#define OHM_PLUGIN_REQUIRES(...) \
+	G_MODULE_EXPORT const gchar *ohm_plugin_requires[] = {__VA_ARGS__,NULL}
+
+#define OHM_PLUGIN_SUGGESTS(...) \
+	G_MODULE_EXPORT const gchar *ohm_plugin_suggests[] = {__VA_ARGS__,NULL}
+
+#define OHM_PLUGIN_PREVENTS(...) \
+	G_MODULE_EXPORT const gchar *ohm_plugin_prevents[] = {__VA_ARGS__,NULL}
+
+typedef void (*OhmPluginHalPropMod)			(OhmPlugin	*plugin,
 							 guint		 id,
 							 const gchar	*key);
-typedef void (*OhmPluginHalCondition) 			(OhmPlugin	*plugin,
+typedef void (*OhmPluginHalCondition)			(OhmPlugin	*plugin,
 							 guint		 id,
 							 const gchar	*name,
 							 const gchar	*detail);
 
-
-#define OHM_INIT_PLUGIN(plugininfo) G_MODULE_EXPORT OhmPluginInfo *ohm_init_plugin (OhmPlugin *plugin) {return &(plugin_info);}
-
 GType		 ohm_plugin_get_type			(void);
-OhmPlugin 	*ohm_plugin_new				(void);
+OhmPlugin	*ohm_plugin_new				(void);
 
-gboolean	 ohm_plugin_preload			(OhmPlugin      *plugin,
-							 const gchar	*name);
-
-gboolean	 ohm_plugin_require			(OhmPlugin	*plugin,
-							 const gchar	*name);
-gboolean	 ohm_plugin_suggest			(OhmPlugin	*plugin,
-							 const gchar	*name);
-gboolean	 ohm_plugin_prevent			(OhmPlugin	*plugin,
+gboolean	 ohm_plugin_load			(OhmPlugin      *plugin,
 							 const gchar	*name);
 
 const gchar	*ohm_plugin_get_name			(OhmPlugin	*plugin);
@@ -99,17 +142,12 @@ gboolean	 ohm_plugin_spawn_async			(OhmPlugin      *plugin,
 							 const gchar	*commandline);
 
 /* used by plugin to manager */
-gboolean	 ohm_plugin_conf_provide		(OhmPlugin      *plugin,
-							 const gchar	*name);
 gboolean	 ohm_plugin_conf_get_key		(OhmPlugin      *plugin,
 							 const gchar	*key,
 							 gint		*value);
 gboolean	 ohm_plugin_conf_set_key		(OhmPlugin      *plugin,
 							 const gchar	*key,
 							 gint		 value);
-gboolean	 ohm_plugin_conf_interested		(OhmPlugin      *plugin,
-							 const gchar	*key,
-							 gint		 id);
 /* used by plugin for hal */
 gboolean	 ohm_plugin_hal_init			(OhmPlugin	*plugin);
 gboolean	 ohm_plugin_hal_use_property_modified	(OhmPlugin	*plugin,
@@ -130,10 +168,10 @@ guint		 ohm_plugin_hal_add_device_capability	(OhmPlugin	*plugin,
 							 const gchar	*capability);
 
 /* used by manager to plugin */
-gboolean	 ohm_plugin_conf_notify			(OhmPlugin      *plugin,
+gboolean	 ohm_plugin_notify			(OhmPlugin      *plugin,
 							 gint		 id,
 							 gint		 value);
-gboolean	 ohm_plugin_coldplug			(OhmPlugin      *plugin);
+gboolean	 ohm_plugin_initialize			(OhmPlugin      *plugin);
 
 G_END_DECLS
 
-- 
1.5.3.GIT


--------------040904070102060909030406
Content-Type: text/x-patch;
 name="0002-update-plugins-to-new-plugin-interface.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="0002-update-plugins-to-new-plugin-interface.patch"



More information about the Ohm-devel mailing list