gobject-introspection r220 - in trunk: . girepository



Author: hp
Date: Wed Apr 23 01:17:24 2008
New Revision: 220
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=220&view=rev

Log:
2008-04-22  Havoc Pennington  <hp pobox com>

	* girepository/gmetadata.c (_g_metadata_init): hack to avoid
 	dlopening a library that is already in the main app, by checking
	whether one of the lib's symbols is already loaded.



Modified:
   trunk/ChangeLog
   trunk/girepository/gmetadata.c

Modified: trunk/girepository/gmetadata.c
==============================================================================
--- trunk/girepository/gmetadata.c	(original)
+++ trunk/girepository/gmetadata.c	Wed Apr 23 01:17:24 2008
@@ -1749,6 +1749,43 @@
   return quark;
 }
 
+static const char*
+find_some_symbol (GMetadata *metadata)
+{
+  Header *header = (Header *) metadata->data;
+  gint i;
+
+  for (i = 0; i < header->n_entries; i++)
+    {
+      DirEntry *entry;
+      
+      entry = g_metadata_get_dir_entry (metadata, i + 1);
+
+      switch (entry->blob_type)
+        {
+        case BLOB_TYPE_FUNCTION:
+          {
+            FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset];
+            
+            if (blob->symbol)
+              return g_metadata_get_string (metadata, blob->symbol);
+          }
+          break;
+        case BLOB_TYPE_OBJECT:
+          {
+            RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset];
+            
+            if (blob->gtype_init)
+              return g_metadata_get_string (metadata, blob->gtype_init);
+          }
+          break;
+        default:
+          break;
+        }
+    }
+
+  return NULL;
+}
 
 static inline void
 _g_metadata_init (GMetadata *metadata)
@@ -1760,20 +1797,56 @@
     {
       const gchar *shlib;
 
-      /* Glade's autoconnect feature and OpenGL's extension mechanism
-       * as used by Clutter rely on dlopen(NULL) to work as a means of
-       * accessing the app's symbols. This keeps us from using
-       * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
-       * in general libraries are not expecting multiple copies of
-       * themselves and are not expecting to be unloaded. So we just
-       * load modules globally for now.
-       */
-      
       shlib = g_metadata_get_string (metadata, header->shared_library);
-      metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY);
+      /* note that NULL shlib means to open the main app, which is allowed */
+
+      /* If we do have a shared lib, first be sure the main app isn't already linked to it */
+      if (shlib != NULL)
+        {
+          const char *symbol_in_module;
+           
+          symbol_in_module = find_some_symbol (metadata);
+          if (symbol_in_module != NULL)
+            {
+              metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+              if (metadata->module == NULL)
+                {
+                  g_warning ("Could not open main app as GModule: %s",
+                             g_module_error ());
+                }
+              else
+                {
+                  void *sym;
+                  if (!g_module_symbol (metadata->module, symbol_in_module, &sym))
+                    {
+                      /* we will try opening the shlib, symbol is not in app already */
+                      g_module_close (metadata->module);
+                      metadata->module = NULL;
+                    }
+                }
+            }
+          else
+            {
+              g_warning ("Could not find any symbols in metadata");
+            }
+        }
+     
       if (metadata->module == NULL)
-        g_warning ("Failed to load shared library referenced by the metadata: %s",
-                   g_module_error ());
+        {
+          /* Glade's autoconnect feature and OpenGL's extension mechanism
+           * as used by Clutter rely on dlopen(NULL) to work as a means of
+           * accessing the app's symbols. This keeps us from using
+           * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
+           * in general libraries are not expecting multiple copies of
+           * themselves and are not expecting to be unloaded. So we just
+           * load modules globally for now.
+           */
+          
+          metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY);
+          if (metadata->module == NULL)
+            g_warning ("Failed to load shared library referenced by the metadata: %s",
+                       g_module_error ());
+        }
     }
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]