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>
|
2000-01-12 Martin Baulig <martin@home-of-linux.org>
|
||||||
|
|
||||||
* lib/init.c (glibtop_init_s): Comment out `_glibtop_init_hook_s'.
|
* lib/init.c (glibtop_init_s): Comment out `_glibtop_init_hook_s'.
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
BEGIN_LIBGTOP_DECLS
|
BEGIN_LIBGTOP_DECLS
|
||||||
|
|
||||||
typedef struct _glibtop_backend_info glibtop_backend_info;
|
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_private glibtop_backend_private;
|
||||||
|
|
||||||
typedef struct _glibtop_backend glibtop_backend;
|
typedef struct _glibtop_backend glibtop_backend;
|
||||||
@@ -52,6 +54,29 @@ struct _glibtop_backend_info
|
|||||||
glibtop_call_vector *call_vector;
|
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
|
struct _glibtop_backend
|
||||||
{
|
{
|
||||||
glibtop_backend_info *info;
|
glibtop_backend_info *info;
|
||||||
@@ -59,15 +84,15 @@ struct _glibtop_backend
|
|||||||
};
|
};
|
||||||
|
|
||||||
long
|
long
|
||||||
glibtop_register_backend (glibtop_backend_info *info);
|
glibtop_register_backend (glibtop_backend_entry *entry);
|
||||||
|
|
||||||
void
|
void
|
||||||
glibtop_unregister_backend (long id);
|
glibtop_unregister_backend (long id);
|
||||||
|
|
||||||
glibtop_backend_info *
|
glibtop_backend_entry *
|
||||||
glibtop_backend_by_id (long id);
|
glibtop_backend_by_id (long id);
|
||||||
|
|
||||||
glibtop_backend_info *
|
glibtop_backend_entry *
|
||||||
glibtop_backend_by_name (const char *backend_name);
|
glibtop_backend_by_name (const char *backend_name);
|
||||||
|
|
||||||
void
|
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
|
backend.c init-backends.c open-backend.c
|
||||||
|
|
||||||
libgtop_la_LDFLAGS = $(LT_VERSION_INFO)
|
libgtop_la_LDFLAGS = $(LT_VERSION_INFO)
|
||||||
|
libgtop_la_LIBADD = $(LIBGTOP_XML_LIB)
|
||||||
|
|
||||||
glibtopdir = $(includedir)/glibtop
|
glibtopdir = $(includedir)/glibtop
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ static GHashTable *_glibtop_backend_list = NULL;
|
|||||||
static long _glibtop_backend_nr = 0;
|
static long _glibtop_backend_nr = 0;
|
||||||
|
|
||||||
long
|
long
|
||||||
glibtop_register_backend (glibtop_backend_info *info)
|
glibtop_register_backend (glibtop_backend_entry *entry)
|
||||||
{
|
{
|
||||||
long id;
|
long id;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ glibtop_register_backend (glibtop_backend_info *info)
|
|||||||
|
|
||||||
g_hash_table_insert (_glibtop_backend_list,
|
g_hash_table_insert (_glibtop_backend_list,
|
||||||
GINT_TO_POINTER (id),
|
GINT_TO_POINTER (id),
|
||||||
info);
|
entry);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ glibtop_unregister_backend (long id)
|
|||||||
GINT_TO_POINTER (id));
|
GINT_TO_POINTER (id));
|
||||||
}
|
}
|
||||||
|
|
||||||
glibtop_backend_info *
|
glibtop_backend_entry *
|
||||||
glibtop_backend_by_id (long id)
|
glibtop_backend_by_id (long id)
|
||||||
{
|
{
|
||||||
return g_hash_table_lookup (_glibtop_backend_list,
|
return g_hash_table_lookup (_glibtop_backend_list,
|
||||||
@@ -65,23 +65,23 @@ glibtop_backend_by_id (long id)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *backend_name;
|
const char *backend_name;
|
||||||
glibtop_backend_info *info;
|
glibtop_backend_entry *entry;
|
||||||
} _find_by_name_param_t;
|
} _find_by_name_param_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_by_name (gpointer key, gpointer value, gpointer user_data)
|
find_by_name (gpointer key, gpointer value, gpointer user_data)
|
||||||
{
|
{
|
||||||
_find_by_name_param_t *param = (_find_by_name_param_t *) 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;
|
return;
|
||||||
|
|
||||||
if (!strcmp (info->name, param->backend_name))
|
if (!strcmp (entry->name, param->backend_name))
|
||||||
param->info = info;
|
param->entry = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
glibtop_backend_info *
|
glibtop_backend_entry *
|
||||||
glibtop_backend_by_name (const char *backend_name)
|
glibtop_backend_by_name (const char *backend_name)
|
||||||
{
|
{
|
||||||
_find_by_name_param_t param = { backend_name, NULL };
|
_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,
|
g_hash_table_foreach (_glibtop_backend_list,
|
||||||
find_by_name, ¶m);
|
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_sysdeps;
|
||||||
extern glibtop_backend_info glibtop_backend_common;
|
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
|
void
|
||||||
glibtop_init_backends (void)
|
glibtop_init_backends (void)
|
||||||
{
|
{
|
||||||
@@ -42,7 +54,147 @@ glibtop_init_backends (void)
|
|||||||
return;
|
return;
|
||||||
backends_initialized = 1;
|
backends_initialized = 1;
|
||||||
|
|
||||||
glibtop_register_backend (&glibtop_backend_server);
|
#if HAVE_LIBXML
|
||||||
glibtop_register_backend (&glibtop_backend_sysdeps);
|
_glibtop_init_gmodule_backends (LIBGTOP_BACKEND_DIR);
|
||||||
glibtop_register_backend (&glibtop_backend_common);
|
#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 <glibtop/backend.h>
|
||||||
|
|
||||||
|
#include <gmodule.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
glibtop_open_backend_l (glibtop *server, const char *backend_name,
|
glibtop_open_backend_l (glibtop *server, const char *backend_name,
|
||||||
u_int64_t features, const char **backend_args)
|
u_int64_t features, const char **backend_args)
|
||||||
{
|
{
|
||||||
|
glibtop_backend_entry *entry;
|
||||||
glibtop_backend_info *info;
|
glibtop_backend_info *info;
|
||||||
glibtop_backend *backend;
|
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;
|
if (!info) return -GLIBTOP_ERROR_NO_SUCH_BACKEND;
|
||||||
|
|
||||||
backend = glibtop_calloc_r (server, 1, sizeof (glibtop_backend));
|
backend = glibtop_calloc_r (server, 1, sizeof (glibtop_backend));
|
||||||
|
Reference in New Issue
Block a user