gvfs r2021 - in trunk: . client common monitor/gphoto2 monitor/hal monitor/proxy



Author: alexl
Date: Tue Sep 23 19:16:06 2008
New Revision: 2021
URL: http://svn.gnome.org/viewvc/gvfs?rev=2021&view=rev

Log:
2008-09-23  Alexander Larsson  <alexl redhat com>

        * monitor/proxy/gproxyvolumemonitor.[ch]:
        * monitor/proxy/gproxyvolumemonitor.h:
        * monitor/proxy/remote-volume-monitor-module.c:
	Only call the IsSupported dbus call when the class
	is actually needed instead of on gio init.
	Don't integrate internal session bus with mainloop
	during is_support code, as that is not necessary yet, and
	it caused problem if done in a thread.
	
	This fixes the trash crash issue in bug #547568.

2008-09-23  Alexander Larsson  <alexl redhat com>

        * client/Makefile.am:
        * common/Makefile.am:
        * common/gmountsource.c:
        * common/gmounttracker.c:
        * monitor/gphoto2/Makefile.am:
        * monitor/hal/Makefile.am:
        * monitor/proxy/Makefile.am:
	Link all modules against the installed libgvfscommon instead
	of duplicating the statically linked one. This is safe wrt
	namespace conflicts, because the modules are opened RTLD_LOCAL
	so the dependencies will not pollute the global namespace.

        * client/gdaemonvfs.c:
	Make the gvfsdbus module persistant. This means we will never
	unload it, and thus not unload libgvfscommon which could
	be problematic. This is not a huge problem, as:
	 + The gio modules will not be loaded anyway unless you use gio
	 + The gvfsdbus module will be persistent anyway as soon as
	   the app references the GVfs object, which likely all gio apps do
	 + The module load order doesn't matter wrt unload order, because
	   all gio modules are loaded before any one is unloaded.
	



Modified:
   trunk/ChangeLog
   trunk/client/Makefile.am
   trunk/client/gdaemonvfs.c
   trunk/common/Makefile.am
   trunk/common/gmountsource.c
   trunk/common/gmounttracker.c
   trunk/monitor/gphoto2/Makefile.am
   trunk/monitor/hal/Makefile.am
   trunk/monitor/proxy/Makefile.am
   trunk/monitor/proxy/gproxyvolumemonitor.c
   trunk/monitor/proxy/gproxyvolumemonitor.h
   trunk/monitor/proxy/remote-volume-monitor-module.c

Modified: trunk/client/Makefile.am
==============================================================================
--- trunk/client/Makefile.am	(original)
+++ trunk/client/Makefile.am	Tue Sep 23 19:16:06 2008
@@ -39,7 +39,7 @@
 	$(NULL)
 
 vfslibs = \
-	$(top_builddir)/common/libgvfscommon-noin.la \
+	$(top_builddir)/common/libgvfscommon.la \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS) \
 	$(NULL)

Modified: trunk/client/gdaemonvfs.c
==============================================================================
--- trunk/client/gdaemonvfs.c	(original)
+++ trunk/client/gdaemonvfs.c	Tue Sep 23 19:16:06 2008
@@ -983,6 +983,14 @@
   if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL) 
     return;
 
+  /* Make this module resident so that we ground the common
+   * library. If that is unloaded we could get into all kinds
+   * of strange situations. This is safe to do even if we loaded
+   * some other common-using module first as all modules are loaded
+   * before any are freed.
+   */
+  g_type_module_use (G_TYPE_MODULE (module));
+  
   g_daemon_vfs_register_type (G_TYPE_MODULE (module));
   g_daemon_volume_monitor_register_types (G_TYPE_MODULE (module));
 

Modified: trunk/common/Makefile.am
==============================================================================
--- trunk/common/Makefile.am	(original)
+++ trunk/common/Makefile.am	Tue Sep 23 19:16:06 2008
@@ -1,6 +1,5 @@
 NULL =
 
-noinst_LTLIBRARIES = libgvfscommon-noin.la
 lib_LTLIBRARIES=libgvfscommon.la
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gvfs \
@@ -9,7 +8,7 @@
 	-DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
 	-DDBUS_API_SUBJECT_TO_CHANGE
 
-libgvfscommon_noin_la_SOURCES = 	\
+libgvfscommon_la_SOURCES = 	\
 	gsysutils.c gsysutils.h \
 	gdbusutils.c gdbusutils.h \
 	gmountspec.c gmountspec.h \
@@ -19,9 +18,6 @@
 	gvfsdaemonprotocol.c gvfsdaemonprotocol.h \
 	$(NULL)
 
-libgvfscommon_noin_la_LIBADD =	\
+libgvfscommon_la_LIBADD =	\
 	$(DBUS_LIBS) 	\
 	$(GLIB_LIBS)
-
-libgvfscommon_la_SOURCES =
-libgvfscommon_la_LIBADD = libgvfscommon-noin.la

Modified: trunk/common/gmountsource.c
==============================================================================
--- trunk/common/gmountsource.c	(original)
+++ trunk/common/gmountsource.c	Tue Sep 23 19:16:06 2008
@@ -35,32 +35,7 @@
   char *obj_path;
 };
 
-/* We use this hack to avoid problems when this code
-   is shared in both the daemon and the client */
-static GType _g_mount_source_get_type (void) G_GNUC_CONST;
-
-#define g_mount_source_get_type _g_mount_source_get_type
 G_DEFINE_TYPE (GMountSource, g_mount_source, G_TYPE_OBJECT)
-#undef g_mount_source_get_type
-
-GType
-g_mount_source_get_type (void)
-{
-  static volatile gsize type_volatile = 0;
-  
-  if (g_once_init_enter (&type_volatile))
-    {
-      GType type;
-      
-      type = g_type_from_name ("GMountSource");
-      if (type == 0)
-	type = _g_mount_source_get_type ();
-      
-      g_once_init_leave (&type_volatile, type);
-    }
-  
-  return type_volatile;
-}
 
 static void
 g_mount_source_finalize (GObject *object)

Modified: trunk/common/gmounttracker.c
==============================================================================
--- trunk/common/gmounttracker.c	(original)
+++ trunk/common/gmounttracker.c	Tue Sep 23 19:16:06 2008
@@ -54,33 +54,7 @@
   DBusConnection *connection;
 };
 
-/* We use this hack to avoid problems when this code
-   is shared in both the daemon and the client */
-static GType _g_mount_tracker_get_type (void) G_GNUC_CONST;
-
-#define g_mount_tracker_get_type _g_mount_tracker_get_type
 G_DEFINE_TYPE (GMountTracker, g_mount_tracker, G_TYPE_OBJECT)
-#undef g_mount_tracker_get_type
-
-GType
-g_mount_tracker_get_type (void)
-{
-  static volatile gsize type_volatile = 0;
-  
-  if (g_once_init_enter (&type_volatile))
-    {
-      GType type;
-      
-      type = g_type_from_name ("GMountTracker");
-      if (type == 0)
-	type = _g_mount_tracker_get_type ();
-      
-      g_once_init_leave (&type_volatile, type);
-    }
-  
-  return type_volatile;
-}
-
 
 static DBusHandlerResult g_mount_tracker_filter_func  (DBusConnection        *conn,
 						       DBusMessage           *message,

Modified: trunk/monitor/gphoto2/Makefile.am
==============================================================================
--- trunk/monitor/gphoto2/Makefile.am	(original)
+++ trunk/monitor/gphoto2/Makefile.am	Tue Sep 23 19:16:06 2008
@@ -40,7 +40,7 @@
 gvfs_gphoto2_volume_monitor_LDADD  =		     			      \
 	$(GLIB_LIBS)                                 			      \
 	$(HAL_LIBS)                                  			      \
-	$(top_builddir)/common/libgvfscommon-noin.la 			      \
+	$(top_builddir)/common/libgvfscommon.la 			      \
 	$(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \
 	$(NULL)
 

Modified: trunk/monitor/hal/Makefile.am
==============================================================================
--- trunk/monitor/hal/Makefile.am	(original)
+++ trunk/monitor/hal/Makefile.am	Tue Sep 23 19:16:06 2008
@@ -42,7 +42,7 @@
 gvfs_hal_volume_monitor_LDADD  =		     			      \
 	$(GLIB_LIBS)                                 			      \
 	$(HAL_LIBS)                                  			      \
-	$(top_builddir)/common/libgvfscommon-noin.la 			      \
+	$(top_builddir)/common/libgvfscommon.la 			      \
 	$(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \
 	$(NULL)
 

Modified: trunk/monitor/proxy/Makefile.am
==============================================================================
--- trunk/monitor/proxy/Makefile.am	(original)
+++ trunk/monitor/proxy/Makefile.am	Tue Sep 23 19:16:06 2008
@@ -33,7 +33,7 @@
 libgioremote_volume_monitor_la_LIBADD  =		     		\
 	$(GLIB_LIBS)                                 			\
 	$(DBUS_LIBS)                                 			\
-	$(top_builddir)/common/libgvfscommon-noin.la 			\
+	$(top_builddir)/common/libgvfscommon.la 			\
 	$(NULL)
 
 ############################################################################
@@ -57,7 +57,7 @@
 libgvfsproxyvolumemonitordaemon_noin_la_LIBADD  =     		\
 	$(GLIB_LIBS)                                 		\
 	$(DBUS_LIBS)                                 		\
-	$(top_builddir)/common/libgvfscommon-noin.la 		\
+	$(top_builddir)/common/libgvfscommon.la 		\
 	$(NULL)
 
 clean-local:

Modified: trunk/monitor/proxy/gproxyvolumemonitor.c
==============================================================================
--- trunk/monitor/proxy/gproxyvolumemonitor.c	(original)
+++ trunk/monitor/proxy/gproxyvolumemonitor.c	Tue Sep 23 19:16:06 2008
@@ -58,6 +58,7 @@
 G_LOCK_DEFINE_STATIC(proxy_vm);
 
 static DBusConnection *the_session_bus = NULL;
+static gboolean the_session_bus_is_integrated = FALSE;
 static GHashTable *the_volume_monitors = NULL;
 
 struct _GProxyVolumeMonitor {
@@ -81,6 +82,30 @@
 
 static void signal_emit_in_idle (gpointer object, const char *signal_name, gpointer other_object);
 
+static gboolean is_supported (GProxyVolumeMonitorClass *klass);
+
+/* The is_supported API is kinda lame and doesn't pass in the class,
+   so we work around this with this hack */
+typedef gboolean (*is_supported_func) (void);
+
+static GProxyVolumeMonitorClass *is_supported_classes[10] = { NULL };
+static gboolean is_supported_0 (void) { return is_supported (is_supported_classes[0]); };
+static gboolean is_supported_1 (void) { return is_supported (is_supported_classes[1]); };
+static gboolean is_supported_2 (void) { return is_supported (is_supported_classes[2]); };
+static gboolean is_supported_3 (void) { return is_supported (is_supported_classes[3]); };
+static gboolean is_supported_4 (void) { return is_supported (is_supported_classes[4]); };
+static gboolean is_supported_5 (void) { return is_supported (is_supported_classes[5]); };
+static gboolean is_supported_6 (void) { return is_supported (is_supported_classes[6]); };
+static gboolean is_supported_7 (void) { return is_supported (is_supported_classes[7]); };
+static gboolean is_supported_8 (void) { return is_supported (is_supported_classes[8]); };
+static gboolean is_supported_9 (void) { return is_supported (is_supported_classes[9]); };
+static is_supported_func is_supported_funcs[] = {
+  is_supported_0, is_supported_1, is_supported_2, is_supported_3,
+  is_supported_4, is_supported_5, is_supported_6, is_supported_7,
+  is_supported_8, is_supported_9,
+  NULL
+};
+
 static char *
 get_match_rule (GProxyVolumeMonitor *monitor)
 {
@@ -606,6 +631,7 @@
 static void
 g_proxy_volume_monitor_init (GProxyVolumeMonitor *monitor)
 {
+  g_proxy_volume_monitor_setup_session_bus_connection (TRUE);
 }
 
 static void
@@ -617,15 +643,22 @@
 typedef struct {
   char *dbus_name;
   gboolean is_native;
+  int is_supported_nr;
 } ProxyClassData;
 
 static ProxyClassData *
 proxy_class_data_new (const char *dbus_name, gboolean is_native)
 {
   ProxyClassData *data;
+  static int is_supported_nr = 0;
+  
   data = g_new0 (ProxyClassData, 1);
   data->dbus_name = g_strdup (dbus_name);
   data->is_native = is_native;
+  data->is_supported_nr = is_supported_nr++;
+
+  g_assert (is_supported_funcs[data->is_supported_nr] != NULL);
+  
   return data;
 }
 
@@ -635,15 +668,79 @@
   ProxyClassData *data = (ProxyClassData *) class_data;
   klass->dbus_name = g_strdup (data->dbus_name);
   klass->is_native = data->is_native;
+  klass->is_supported_nr = data->is_supported_nr;
   g_proxy_volume_monitor_class_intern_init (klass);
 }
 
 static gboolean
-is_supported (void)
+is_remote_monitor_supported (const char *dbus_name)
 {
-  if (the_session_bus != NULL)
-    return TRUE;
-  return FALSE;
+  DBusMessage *message;
+  DBusMessage *reply;
+  DBusError dbus_error;
+  dbus_bool_t is_supported;
+
+  message = NULL;
+  reply = NULL;
+  is_supported = FALSE;
+
+  message = dbus_message_new_method_call (dbus_name,
+                                          "/",
+                                          "org.gtk.Private.RemoteVolumeMonitor",
+                                          "IsSupported");
+  if (message == NULL)
+    {
+      g_warning ("Cannot allocate memory for DBusMessage");
+      goto fail;
+    }
+  dbus_error_init (&dbus_error);
+  reply = dbus_connection_send_with_reply_and_block (the_session_bus,
+                                                     message,
+                                                     -1,
+                                                     &dbus_error);
+  if (dbus_error_is_set (&dbus_error))
+    {
+      g_warning ("invoking IsSupported() failed for remote volume monitor with dbus name %s: %s: %s",
+                 dbus_name,
+                 dbus_error.name,
+                 dbus_error.message);
+      dbus_error_free (&dbus_error);
+      goto fail;
+    }
+
+  if (!dbus_message_get_args (reply, &dbus_error,
+                              DBUS_TYPE_BOOLEAN, &is_supported,
+                              DBUS_TYPE_INVALID))
+    {
+      g_warning ("Error parsing args in reply for IsSupported(): %s: %s", dbus_error.name, dbus_error.message);
+      dbus_error_free (&dbus_error);
+      goto fail;
+    }
+
+  if (!is_supported)
+    g_warning ("remote volume monitor with dbus name %s is not supported", dbus_name);
+
+ fail:
+  if (message != NULL)
+    dbus_message_unref (message);
+  if (reply != NULL)
+    dbus_message_unref (reply);
+  return is_supported;
+}
+
+static gboolean
+is_supported (GProxyVolumeMonitorClass *klass)
+{
+  gboolean res;
+
+  G_LOCK (proxy_vm);
+  res = g_proxy_volume_monitor_setup_session_bus_connection (FALSE);
+  G_UNLOCK (proxy_vm);
+  
+  if (res)
+    res = is_remote_monitor_supported (klass->dbus_name);
+
+  return res;
 }
 
 static GVolume *
@@ -702,6 +799,7 @@
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
   GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass);
+  int i;
 
   gobject_class->constructor = g_proxy_volume_monitor_constructor;
   gobject_class->finalize = g_proxy_volume_monitor_finalize;
@@ -712,7 +810,10 @@
   monitor_class->get_volume_for_uuid = get_volume_for_uuid;
   monitor_class->get_mount_for_uuid = get_mount_for_uuid;
   monitor_class->adopt_orphan_mount = adopt_orphan_mount;
-  monitor_class->is_supported = is_supported;
+
+  i = klass->is_supported_nr;
+  is_supported_classes[i] = klass;
+  monitor_class->is_supported = is_supported_funcs[i];
 
   native_class->get_mount_for_mount_path = get_mount_for_mount_path;
 }
@@ -1041,47 +1142,47 @@
                                   priority);
 }
 
+/* Call with proxy_vm lock held */
 gboolean
-g_proxy_volume_monitor_setup_session_bus_connection (void)
+g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration)
 {
   gboolean ret;
   DBusError dbus_error;
 
   ret = FALSE;
 
-  G_LOCK (proxy_vm);
   if (the_session_bus != NULL)
-    {
-      g_warning ("session bus connection is already up!");
-      dbus_connection_ref (the_session_bus);
-      goto out;
-    }
+    goto has_bus_already;
 
   /* This is so that system daemons can use gio
    * without spawning private dbus instances.
    * See bug 526454.
    */
   if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
-    {
-      goto out;
-    }
+    goto out;
 
   dbus_error_init (&dbus_error);
   the_session_bus = dbus_bus_get_private (DBUS_BUS_SESSION, &dbus_error);
-  if (dbus_error_is_set (&dbus_error)) {
-    g_warning ("cannot connect to the session bus: %s: %s", dbus_error.name, dbus_error.message);
-    dbus_error_free (&dbus_error);
-    goto out;
-  }
-
-  _g_dbus_connection_integrate_with_main (the_session_bus);
+  if (dbus_error_is_set (&dbus_error))
+    {
+      g_warning ("cannot connect to the session bus: %s: %s", dbus_error.name, dbus_error.message);
+      dbus_error_free (&dbus_error);
+      goto out;
+    }
 
   the_volume_monitors = g_hash_table_new (g_direct_hash, g_direct_equal);
 
+ has_bus_already:
+  
+  if (need_integration && !the_session_bus_is_integrated)
+    {
+      _g_dbus_connection_integrate_with_main (the_session_bus);
+      the_session_bus_is_integrated = TRUE;
+    }
+  
   ret = TRUE;
 
  out:
-  G_UNLOCK (proxy_vm);
   return ret;
 }
 
@@ -1091,8 +1192,9 @@
   G_LOCK (proxy_vm);
   if (the_session_bus != NULL)
     {
-      /* it would be nice to check that refcount==1 here */
-      _g_dbus_connection_remove_from_main (the_session_bus);
+      if (the_session_bus_is_integrated)
+        _g_dbus_connection_remove_from_main (the_session_bus);
+      the_session_bus_is_integrated = FALSE;      
       dbus_connection_close (the_session_bus);
       the_session_bus = NULL;
 
@@ -1102,62 +1204,6 @@
   G_UNLOCK (proxy_vm);
 }
 
-static gboolean
-is_remote_monitor_supported (const char *dbus_name)
-{
-  DBusMessage *message;
-  DBusMessage *reply;
-  DBusError dbus_error;
-  dbus_bool_t is_supported;
-
-  message = NULL;
-  reply = NULL;
-  is_supported = FALSE;
-
-  message = dbus_message_new_method_call (dbus_name,
-                                          "/",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "IsSupported");
-  if (message == NULL)
-    {
-      g_warning ("Cannot allocate memory for DBusMessage");
-      goto fail;
-    }
-  dbus_error_init (&dbus_error);
-  reply = dbus_connection_send_with_reply_and_block (the_session_bus,
-                                                     message,
-                                                     -1,
-                                                     &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
-    {
-      g_warning ("invoking IsSupported() failed for remote volume monitor with dbus name %s: %s: %s",
-                 dbus_name,
-                 dbus_error.name,
-                 dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto fail;
-    }
-
-  if (!dbus_message_get_args (reply, &dbus_error,
-                              DBUS_TYPE_BOOLEAN, &is_supported,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args in reply for IsSupported(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto fail;
-    }
-
-  if (!is_supported)
-    g_warning ("remote volume monitor with dbus name %s is not supported", dbus_name);
-
- fail:
-  if (message != NULL)
-    dbus_message_unref (message);
-  if (reply != NULL)
-    dbus_message_unref (reply);
-  return is_supported;
-}
-
 void
 g_proxy_volume_monitor_register (GIOModule *module)
 {
@@ -1256,14 +1302,11 @@
               native_priority = 0;
             }
 
-          if (is_remote_monitor_supported (dbus_name))
-            {
-              register_volume_monitor (G_TYPE_MODULE (module),
-                                       type_name,
-                                       dbus_name,
-                                       is_native,
-                                       native_priority);
-            }
+          register_volume_monitor (G_TYPE_MODULE (module),
+                                   type_name,
+                                   dbus_name,
+                                   is_native,
+                                   native_priority);
 
         cont:
 

Modified: trunk/monitor/proxy/gproxyvolumemonitor.h
==============================================================================
--- trunk/monitor/proxy/gproxyvolumemonitor.h	(original)
+++ trunk/monitor/proxy/gproxyvolumemonitor.h	Tue Sep 23 19:16:06 2008
@@ -49,6 +49,7 @@
   GNativeVolumeMonitorClass parent_class;
   char *dbus_name;
   gboolean is_native;
+  int is_supported_nr;
 };
 
 GType g_proxy_volume_monitor_get_type (void) G_GNUC_CONST;
@@ -63,7 +64,7 @@
 DBusConnection *g_proxy_volume_monitor_get_dbus_connection (GProxyVolumeMonitor *volume_monitor);
 const char     *g_proxy_volume_monitor_get_dbus_name       (GProxyVolumeMonitor *volume_monitor);
 
-gboolean g_proxy_volume_monitor_setup_session_bus_connection (void);
+gboolean g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration);
 void g_proxy_volume_monitor_teardown_session_bus_connection (void);
 
 

Modified: trunk/monitor/proxy/remote-volume-monitor-module.c
==============================================================================
--- trunk/monitor/proxy/remote-volume-monitor-module.c	(original)
+++ trunk/monitor/proxy/remote-volume-monitor-module.c	Tue Sep 23 19:16:06 2008
@@ -43,9 +43,6 @@
   bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
-  if (!g_proxy_volume_monitor_setup_session_bus_connection ())
-    goto out;
-
   g_proxy_drive_register (module);
   g_proxy_mount_register (module);
   g_proxy_volume_register (module);



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