New type. (glibtop_backend_module): New private type.

2000-01-12  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/backend.h (glibtop_backend_entry): New type.
	(glibtop_backend_module): New private type.

	* lib/backend.c (glibtop_register_backend): This now takes a
	`glibtop_backend_entry' argument, not a `glibtop_backend_info' one.
	(glibtop_backend_by_id): Return a `glibtop_backend_entry' type,
	not a `glibtop_backend_info' one.
	(glibtop_backend_by_name): Likewise.

	* lib/init-backends.c: If we have libxml, read all `.backend' files
	in $(LIBGTOP_BACKEND_DIR), XML parse them and register them via
	`glibtop_backend_register'. This builds a list of all currently
	supported backends without actually loading them into memory.

	* lib/open-backend.c (glibtop_open_backend_l): GModule load the
	backend if it's not already in memory.
This commit is contained in:
Martin Baulig
2000-01-12 20:37:21 +00:00
committed by Martin Baulig
parent 8d532c6298
commit e2e5c3a1cc
6 changed files with 249 additions and 17 deletions

View File

@@ -1,3 +1,22 @@
2000-01-12 Martin Baulig <martin@home-of-linux.org>
* include/glibtop/backend.h (glibtop_backend_entry): New type.
(glibtop_backend_module): New private type.
* lib/backend.c (glibtop_register_backend): This now takes a
`glibtop_backend_entry' argument, not a `glibtop_backend_info' one.
(glibtop_backend_by_id): Return a `glibtop_backend_entry' type,
not a `glibtop_backend_info' one.
(glibtop_backend_by_name): Likewise.
* lib/init-backends.c: If we have libxml, read all `.backend' files
in $(LIBGTOP_BACKEND_DIR), XML parse them and register them via
`glibtop_backend_register'. This builds a list of all currently
supported backends without actually loading them into memory.
* lib/open-backend.c (glibtop_open_backend_l): GModule load the
backend if it's not already in memory.
2000-01-12 Martin Baulig <martin@home-of-linux.org>
* lib/init.c (glibtop_init_s): Comment out `_glibtop_init_hook_s'.

View File

@@ -34,6 +34,8 @@
BEGIN_LIBGTOP_DECLS
typedef struct _glibtop_backend_info glibtop_backend_info;
typedef struct _glibtop_backend_entry glibtop_backend_entry;
typedef struct _glibtop_backend_module glibtop_backend_module;
typedef struct _glibtop_backend_private glibtop_backend_private;
typedef struct _glibtop_backend glibtop_backend;
@@ -52,6 +54,29 @@ struct _glibtop_backend_info
glibtop_call_vector *call_vector;
};
#ifdef _IN_LIBGTOP
#include <gmodule.h>
/* private structure */
struct _glibtop_backend_module
{
int refcount;
GModule *module;
};
#endif /* _IN_LIBGTOP */
struct _glibtop_backend_entry
{
char *name;
char *libtool_name;
char *shlib_name;
glibtop_backend_info *info;
glibtop_backend_module *_priv;
};
struct _glibtop_backend
{
glibtop_backend_info *info;
@@ -59,15 +84,15 @@ struct _glibtop_backend
};
long
glibtop_register_backend (glibtop_backend_info *info);
glibtop_register_backend (glibtop_backend_entry *entry);
void
glibtop_unregister_backend (long id);
glibtop_backend_info *
glibtop_backend_entry *
glibtop_backend_by_id (long id);
glibtop_backend_info *
glibtop_backend_entry *
glibtop_backend_by_name (const char *backend_name);
void

View File

@@ -9,6 +9,7 @@ libgtop_la_SOURCES = init.c open.c close.c lib.c parameter.c \
backend.c init-backends.c open-backend.c
libgtop_la_LDFLAGS = $(LT_VERSION_INFO)
libgtop_la_LIBADD = $(LIBGTOP_XML_LIB)
glibtopdir = $(includedir)/glibtop

View File

@@ -33,7 +33,7 @@ static GHashTable *_glibtop_backend_list = NULL;
static long _glibtop_backend_nr = 0;
long
glibtop_register_backend (glibtop_backend_info *info)
glibtop_register_backend (glibtop_backend_entry *entry)
{
long id;
@@ -44,7 +44,7 @@ glibtop_register_backend (glibtop_backend_info *info)
g_hash_table_insert (_glibtop_backend_list,
GINT_TO_POINTER (id),
info);
entry);
return id;
}
@@ -56,7 +56,7 @@ glibtop_unregister_backend (long id)
GINT_TO_POINTER (id));
}
glibtop_backend_info *
glibtop_backend_entry *
glibtop_backend_by_id (long id)
{
return g_hash_table_lookup (_glibtop_backend_list,
@@ -65,23 +65,23 @@ glibtop_backend_by_id (long id)
typedef struct {
const char *backend_name;
glibtop_backend_info *info;
glibtop_backend_entry *entry;
} _find_by_name_param_t;
static void
find_by_name (gpointer key, gpointer value, gpointer user_data)
{
_find_by_name_param_t *param = (_find_by_name_param_t *) user_data;
glibtop_backend_info *info = (glibtop_backend_info *) value;
glibtop_backend_entry *entry = (glibtop_backend_entry *) value;
if (!info || !info->name || param->info)
if (!entry || !entry->name || param->entry)
return;
if (!strcmp (info->name, param->backend_name))
param->info = info;
if (!strcmp (entry->name, param->backend_name))
param->entry = entry;
}
glibtop_backend_info *
glibtop_backend_entry *
glibtop_backend_by_name (const char *backend_name)
{
_find_by_name_param_t param = { backend_name, NULL };
@@ -89,5 +89,5 @@ glibtop_backend_by_name (const char *backend_name)
g_hash_table_foreach (_glibtop_backend_list,
find_by_name, &param);
return param.info;
return param.entry;
}

View File

@@ -33,6 +33,18 @@ extern glibtop_backend_info glibtop_backend_server;
extern glibtop_backend_info glibtop_backend_sysdeps;
extern glibtop_backend_info glibtop_backend_common;
#if HAVE_LIBXML
#define LIBGTOP_XML_NAMESPACE "http://www.home-of-linux.org/libgtop/1.1"
#include <gnome-xml/parser.h>
#include <dirent.h>
static void _glibtop_init_gmodule_backends (const char *);
#endif /* HAVE_LIBXML */
void
glibtop_init_backends (void)
{
@@ -42,7 +54,147 @@ glibtop_init_backends (void)
return;
backends_initialized = 1;
glibtop_register_backend (&glibtop_backend_server);
glibtop_register_backend (&glibtop_backend_sysdeps);
glibtop_register_backend (&glibtop_backend_common);
#if HAVE_LIBXML
_glibtop_init_gmodule_backends (LIBGTOP_BACKEND_DIR);
#endif
}
#if HAVE_LIBXML
static gchar *
_get_library_filename (xmlDocPtr doc, xmlNodePtr cur, const char *directory)
{
char *filename = xmlNodeListGetString (doc, cur->childs, 1);
gchar *retval;
if (!filename)
return NULL;
/* already absolute */
if (filename [0] == '/')
retval = g_strdup (filename);
else
retval = g_strdup_printf ("%s/%s", directory, filename);
return retval;
}
static glibtop_backend_entry *
_parseBackend (xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, const char *dir)
{
glibtop_backend_entry *ret = NULL;
/*
* allocate the struct
*/
ret = g_new0 (glibtop_backend_entry, 1);
/* We don't care what the top level element name is */
cur = cur->childs;
while (cur != NULL) {
if ((!strcmp (cur->name, "Name")) && (cur->ns == ns))
ret->name = xmlNodeListGetString
(doc, cur->childs, 1);
if ((!strcmp (cur->name, "Location")) && (cur->ns == ns)) {
xmlNodePtr sub = cur->childs;
while (sub != NULL) {
if ((!strcmp (sub->name, "LibtoolName")) && (sub->ns == ns))
ret->libtool_name = _get_library_filename (doc, sub, dir);
if ((!strcmp (sub->name, "ShlibName")) && (sub->ns == ns))
ret->shlib_name = _get_library_filename (doc, sub, dir);
sub = sub->next;
}
}
cur = cur->next;
}
return ret;
}
static void
_glibtop_init_gmodule_backends (const char *directory)
{
DIR *dir;
struct dirent *entry;
dir = opendir (directory);
if (!dir) return;
while ((entry = readdir (dir)) != NULL) {
size_t len = strlen (entry->d_name);
gchar *filename;
xmlDocPtr doc;
xmlNsPtr ns;
xmlNodePtr cur;
if (len < 8)
continue;
if (strcmp (entry->d_name+len-8, ".backend"))
continue;
filename = g_strdup_printf ("%s/%s", directory, entry->d_name);
doc = xmlParseFile (filename);
if (!doc) {
g_warning ("Cannot parse %s", filename);
g_free (filename);
continue;
}
/* Make sure the document is of the right kind */
cur = xmlDocGetRootElement (doc);
if (!cur) {
xmlFreeDoc (doc);
g_free (filename);
continue;
}
ns = xmlSearchNsByHref (doc, cur, LIBGTOP_XML_NAMESPACE);
if (!ns) {
g_warning ("File %s of wrong type; LibGTop Namespace not found",
filename);
g_free (filename);
xmlFreeDoc (doc);
continue;
}
if (strcmp (cur->name, "Backends")) {
g_warning ("File %s of the wrong type, root node != 'Backends'",
filename);
g_free (filename);
xmlFreeDoc (doc);
continue;
}
cur = cur->childs;
while (cur != NULL) {
glibtop_backend_entry *backend;
if ((!strcmp(cur->name, "Backend")) && (cur->ns == ns)) {
backend = _parseBackend (doc, ns, cur, directory);
if (!backend) {
g_warning ("File %s of wrong type; cannot parse",
filename);
continue;
}
glibtop_register_backend (backend);
}
cur = cur->next;
}
g_free (filename);
xmlFreeDoc (doc);
}
closedir (dir);
}
#endif /* HAVE_LIBXML */

View File

@@ -29,14 +29,49 @@
#include <glibtop/backend.h>
#include <gmodule.h>
int
glibtop_open_backend_l (glibtop *server, const char *backend_name,
u_int64_t features, const char **backend_args)
{
glibtop_backend_entry *entry;
glibtop_backend_info *info;
glibtop_backend *backend;
info = glibtop_backend_by_name (backend_name);
entry = glibtop_backend_by_name (backend_name);
if (!entry) return -GLIBTOP_ERROR_NO_SUCH_BACKEND;
if (!entry->_priv) {
entry->_priv = g_new0 (glibtop_backend_module, 1);
entry->_priv->module = g_module_open (entry->shlib_name,
G_MODULE_BIND_LAZY);
if (!entry->_priv->module) {
glibtop_warn_r (server, "Cannot open shared library `%s' "
"for backend `%s'", entry->shlib_name,
entry->name);
return -GLIBTOP_ERROR_NO_SUCH_BACKEND;
}
if (!g_module_symbol (entry->_priv->module,
"LibGTopBackendInfo",
(gpointer*) &entry->info)) {
glibtop_warn_r (server, "Library `%s' is not a valid "
"LibGTop Backend library (start symbol not found)",
entry->shlib_name);
g_module_close (entry->_priv->module);
g_free (entry->_priv);
entry->_priv = NULL;
return -GLIBTOP_ERROR_NO_SUCH_BACKEND;
}
entry->_priv->refcount++;
}
info = entry->info;
if (!info) return -GLIBTOP_ERROR_NO_SUCH_BACKEND;
backend = glibtop_calloc_r (server, 1, sizeof (glibtop_backend));