mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-09 12:25:48 +01:00
[typelib] Clean up dlopen handling
It's was busted that g_typelib_new_* does the dlopen() since that caused g-ir-compiler to load the modules even though it wasn't going to do anything with them. Instead, change things so that g_module_symbol does the dlopen on-demand. Remove the extra dlopen(NULL) inside girepository.c, we had another already in gtypelib.c. Thanks to Owen Taylor for suggesting this approach.
This commit is contained in:
parent
90de854ee5
commit
1735ebde9a
@ -363,9 +363,6 @@ register_internal (GIRepository *repository,
|
||||
g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
|
||||
}
|
||||
|
||||
if (typelib->modules == NULL)
|
||||
typelib->modules = g_list_append(typelib->modules, g_module_open (NULL, 0));
|
||||
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
73
gtypelib.c
73
gtypelib.c
@ -1946,21 +1946,20 @@ g_typelib_error_quark (void)
|
||||
return quark;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_g_typelib_init (GTypelib *typelib)
|
||||
static void
|
||||
_g_typelib_do_dlopen (GTypelib *typelib)
|
||||
{
|
||||
Header *header;
|
||||
const char *shlib_str;
|
||||
|
||||
header = (Header *) typelib->data;
|
||||
if (header->shared_library)
|
||||
{
|
||||
const gchar *shlib_str;
|
||||
GModule *app_module = NULL;
|
||||
|
||||
shlib_str = g_typelib_get_string (typelib, header->shared_library);
|
||||
/* note that NULL shlib means to open the main app, which is allowed */
|
||||
if (header->shared_library)
|
||||
shlib_str = g_typelib_get_string (typelib, header->shared_library);
|
||||
else
|
||||
shlib_str = NULL;
|
||||
|
||||
if (shlib_str != NULL)
|
||||
if (shlib_str != NULL && shlib_str[0] != '\0')
|
||||
{
|
||||
gchar **shlibs;
|
||||
gint i;
|
||||
@ -2018,16 +2017,30 @@ _g_typelib_init (GTypelib *typelib)
|
||||
|
||||
g_strfreev (shlibs);
|
||||
}
|
||||
|
||||
/* we should make sure the app_module in the end of list so that
|
||||
* it's last symbol source when loading any symbols from modules.
|
||||
* See comments in g_typelib_symbol */
|
||||
app_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
if (app_module)
|
||||
typelib->modules = g_list_append (typelib->modules, app_module);
|
||||
else
|
||||
{
|
||||
/* If there's no shared-library entry for this module, assume that
|
||||
* the module is for the application. Some of the hand-written .gir files
|
||||
* in gobject-introspection don't have shared-library entries, but no one
|
||||
* is really going to be calling g_module_symbol on them either.
|
||||
*/
|
||||
GModule *module = g_module_open (NULL, 0);
|
||||
if (module == NULL)
|
||||
g_warning ("gtypelib.c: Failed to g_module_open (NULL): %s", g_module_error ());
|
||||
else
|
||||
typelib->modules = g_list_prepend (typelib->modules, module);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_g_typelib_ensure_open (GTypelib *typelib)
|
||||
{
|
||||
if (typelib->open_attempted)
|
||||
return;
|
||||
typelib->open_attempted = TRUE;
|
||||
_g_typelib_do_dlopen (typelib);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_typelib_new_from_memory:
|
||||
* @memory: address of memory chunk containing the typelib
|
||||
@ -2049,7 +2062,7 @@ g_typelib_new_from_memory (guchar *memory, gsize len)
|
||||
meta->len = len;
|
||||
meta->owns_memory = TRUE;
|
||||
meta->modules = NULL;
|
||||
_g_typelib_init (meta);
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
@ -2072,7 +2085,7 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len)
|
||||
meta->len = len;
|
||||
meta->owns_memory = FALSE;
|
||||
meta->modules = NULL;
|
||||
_g_typelib_init (meta);
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
@ -2094,7 +2107,7 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile)
|
||||
meta->owns_memory = FALSE;
|
||||
meta->data = (guchar *) g_mapped_file_get_contents (mfile);
|
||||
meta->len = g_mapped_file_get_length (mfile);
|
||||
_g_typelib_init (meta);
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
@ -2141,20 +2154,18 @@ g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
_g_typelib_ensure_open (typelib);
|
||||
|
||||
/*
|
||||
* We want to be able to add symbols to an app or an auxiliary
|
||||
* library to fill in gaps in an introspected library. However,
|
||||
* normally we would only look for symbols in the main library
|
||||
* (the first items in typelib->modules).
|
||||
* The reason for having multiple modules dates from gir-repository
|
||||
* when it was desired to inject code (accessors, etc.) into an
|
||||
* existing library. In that situation, the first module listed
|
||||
* will be the custom one, which overrides the main one. A bit
|
||||
* inefficient, but the problem will go away when gir-repository
|
||||
* does.
|
||||
*
|
||||
* A more elaborate solution is probably possible, but as a
|
||||
* simple approach for now, if we fail to find a symbol we look
|
||||
* for it in the global module (the last item in type->modules).
|
||||
*
|
||||
* This would not be very efficient if it happened often, since
|
||||
* we always do the failed lookup above first, but very few
|
||||
* symbols should be outside of the main libraries in
|
||||
* typelib->modules so it doesn't matter.
|
||||
* For modules with no shared library, we dlopen'd the current
|
||||
* process above.
|
||||
*/
|
||||
for (l = typelib->modules; l; l = l->next)
|
||||
{
|
||||
|
@ -1021,6 +1021,7 @@ struct _GTypelib {
|
||||
gboolean owns_memory;
|
||||
GMappedFile *mfile;
|
||||
GList *modules;
|
||||
gboolean open_attempted;
|
||||
};
|
||||
|
||||
DirEntry *g_typelib_get_dir_entry (GTypelib *typelib,
|
||||
|
Loading…
x
Reference in New Issue
Block a user