Bug 713827: dlopen() gconf library in mozgnome component r=karlt
authorChris Coulson <chris.coulson@canonical.com>
Thu, 05 Jan 2012 11:19:46 +1300
changeset 83792 04244dc1f49853dfff572a8b8664cd52135c1ca3
parent 83791 f1e771f3c2cdb2b976af4be9c0a240374fd05b6b
child 83793 21c2b8c54c54ed4c110d500e7934d2a0316e9b11
push id4594
push userktomlinson@mozilla.com
push dateThu, 05 Jan 2012 04:57:14 +0000
treeherdermozilla-inbound@505df7671545 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs713827
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 713827: dlopen() gconf library in mozgnome component r=karlt
configure.in
toolkit/system/gnome/nsGConfService.cpp
--- a/configure.in
+++ b/configure.in
@@ -5308,17 +5308,17 @@ then
     MOZ_ARG_DISABLE_BOOL(gconf,
     [  --disable-gconf      Disable Gconf support ],
         MOZ_ENABLE_GCONF=,
         MOZ_ENABLE_GCONF=force)
 
     if test "$MOZ_ENABLE_GCONF"
     then
         PKG_CHECK_MODULES(MOZ_GCONF, gconf-2.0 >= $GCONF_VERSION gobject-2.0 ,[
-            MOZ_GCONF_LIBS=`echo $MOZ_GCONF_LIBS | sed 's/-llinc\>//'`
+            MOZ_GCONF_LIBS=`$PKG_CONFIG --libs gobject-2.0`
             MOZ_ENABLE_GCONF=1
         ],[
             if test "$MOZ_ENABLE_GCONF" = "force"
             then
                 AC_MSG_ERROR([* * * Could not find gconf-2.0 ])
             fi
             MOZ_ENABLE_GCONF=
         ])
--- a/toolkit/system/gnome/nsGConfService.cpp
+++ b/toolkit/system/gnome/nsGConfService.cpp
@@ -31,34 +31,103 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "mozilla/Util.h"
 #include "nsGConfService.h"
 #include "nsStringAPI.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIMutableArray.h"
+#include "prlink.h"
 
 #include <gconf/gconf-client.h>
 
+using namespace mozilla;
+
+#define GCONF_FUNCTIONS \
+  FUNC(gconf_client_get_default, GConfClient*, (void)) \
+  FUNC(gconf_client_get_bool, gboolean, (GConfClient*, const gchar*, GError**)) \
+  FUNC(gconf_client_get_string, gchar*, (GConfClient*, const gchar*, GError**)) \
+  FUNC(gconf_client_get_int, gint, (GConfClient*, const gchar*, GError**)) \
+  FUNC(gconf_client_get_float, gdouble, (GConfClient*, const gchar*, GError**)) \
+  FUNC(gconf_client_get_list, GSList*, (GConfClient*, const gchar*, GConfValueType, GError**)) \
+  FUNC(gconf_client_set_bool, gboolean, (GConfClient*, const gchar*, gboolean, GError**)) \
+  FUNC(gconf_client_set_string, gboolean, (GConfClient*, const gchar*, const gchar*, GError**)) \
+  FUNC(gconf_client_set_int, gboolean, (GConfClient*, const gchar*, gint, GError**)) \
+  FUNC(gconf_client_set_float, gboolean, (GConfClient*, const gchar*, gdouble, GError**)) \
+  FUNC(gconf_client_unset, gboolean, (GConfClient*, const gchar*, GError**))
+
+#define FUNC(name, type, params) \
+  typedef type (*_##name##_fn) params; \
+  static _##name##_fn _##name;
+
+GCONF_FUNCTIONS
+
+#undef FUNC
+
+#define gconf_client_get_default _gconf_client_get_default
+#define gconf_client_get_bool _gconf_client_get_bool
+#define gconf_client_get_string _gconf_client_get_string
+#define gconf_client_get_int _gconf_client_get_int
+#define gconf_client_get_float _gconf_client_get_float
+#define gconf_client_get_list _gconf_client_get_list
+#define gconf_client_set_bool _gconf_client_set_bool
+#define gconf_client_set_string _gconf_client_set_string
+#define gconf_client_set_int _gconf_client_set_int
+#define gconf_client_set_float _gconf_client_set_float
+#define gconf_client_unset _gconf_client_unset
+
+static PRLibrary *gconfLib = nsnull;
+
+typedef void (*nsGConfFunc)();
+struct nsGConfDynamicFunction {
+  const char *functionName;
+  nsGConfFunc *function;
+};
+
 nsGConfService::~nsGConfService()
 {
   if (mClient)
     g_object_unref(mClient);
+
+  // We don't unload gconf here because liborbit uses atexit(). In addition to
+  // this, it's not a good idea to unload any gobject based library, as it
+  // leaves types registered in glib's type system
 }
 
 nsresult
 nsGConfService::Init()
 {
+#define FUNC(name, type, params) { #name, (nsGConfFunc *)&_##name },
+  static const nsGConfDynamicFunction kGConfSymbols[] = {
+    GCONF_FUNCTIONS
+  };
+#undef FUNC
+
+  if (!gconfLib) {
+    gconfLib = PR_LoadLibrary("libgconf-2.so.4");
+    if (!gconfLib)
+      return NS_ERROR_FAILURE;
+  }
+
+  for (PRUint32 i = 0; i < ArrayLength(kGConfSymbols); i++) {
+    *kGConfSymbols[i].function =
+      PR_FindFunctionSymbol(gconfLib, kGConfSymbols[i].functionName);
+    if (!*kGConfSymbols[i].function) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+
   mClient = gconf_client_get_default();
   return mClient ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMPL_ISUPPORTS1(nsGConfService, nsIGConfService)
 
 NS_IMETHODIMP
 nsGConfService::GetBool(const nsACString &aKey, bool *aResult)