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:
committed by
Martin Baulig
parent
8d532c6298
commit
e2e5c3a1cc
19
ChangeLog
19
ChangeLog
@@ -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'.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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, ¶m);
|
||||
|
||||
return param.info;
|
||||
return param.entry;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user