[gvfs] Do not sent user invisible mounts if not needed



commit ceb0daa48bd6b5144873a4984572c2781fa4a7ac
Author: Ondrej Holy <oholy redhat com>
Date:   Wed Jan 4 10:31:08 2017 +0100

    Do not sent user invisible mounts if not needed
    
    g_volume_monitor_get() might be really slow if there is too many
    mounts, because the list of the mounts is send over D-Bus. It can
    simply happen due to user invisible mounts, e.g. http. User invisible
    mounts are ignored by the volume monitor, so it is useless to send
    them over D-Bus. Improve the D-Bus API and don't send the user
    invisible mounts if it is not needed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775600

 client/gdaemonvolumemonitor.c |   26 +++++++++--------------
 common/gmounttracker.c        |   45 +++++++++++++++++++++++++++++++++++-----
 common/gmounttracker.h        |    3 +-
 common/org.gtk.vfs.xml        |    4 +++
 daemon/gvfsbackendafpbrowse.c |    2 +-
 daemon/gvfsbackendsmbbrowse.c |    2 +-
 daemon/mount.c                |   43 +++++++++++++++++++++++++++++++++-----
 7 files changed, 94 insertions(+), 31 deletions(-)
---
diff --git a/client/gdaemonvolumemonitor.c b/client/gdaemonvolumemonitor.c
index b73453b..dc1407d 100644
--- a/client/gdaemonvolumemonitor.c
+++ b/client/gdaemonvolumemonitor.c
@@ -148,14 +148,11 @@ mount_added (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info)
       return;
     }
 
-  if (mount_info->user_visible)
-    {
-      mount = g_daemon_mount_new (mount_info, G_VOLUME_MONITOR (daemon_monitor));
-      daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
+  mount = g_daemon_mount_new (mount_info, G_VOLUME_MONITOR (daemon_monitor));
+  daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
 
-      /* Ref for the signal emission, other ref is owned by volume monitor */
-      g_object_ref (mount);
-    }
+  /* Ref for the signal emission, other ref is owned by volume monitor */
+  g_object_ref (mount);
   
   G_UNLOCK (daemon_vm);
 
@@ -177,8 +174,7 @@ mount_removed (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info)
   mount = find_mount_by_mount_info (daemon_monitor, mount_info);
   if (!mount)
     {
-      if (mount_info->user_visible)
-       g_warning (G_STRLOC ": An unknown mount was removed!");
+      g_warning (G_STRLOC ": An unknown mount was removed!");
       
       G_UNLOCK (daemon_vm);
       return;
@@ -203,7 +199,7 @@ g_daemon_volume_monitor_init (GDaemonVolumeMonitor *daemon_monitor)
 
   _the_daemon_volume_monitor = daemon_monitor;
 
-  daemon_monitor->mount_tracker = g_mount_tracker_new (_g_daemon_vfs_get_async_bus ());
+  daemon_monitor->mount_tracker = g_mount_tracker_new (_g_daemon_vfs_get_async_bus (), TRUE);
 
   g_signal_connect_swapped (daemon_monitor->mount_tracker, "mounted",
                            (GCallback) mount_added, daemon_monitor);
@@ -215,12 +211,10 @@ g_daemon_volume_monitor_init (GDaemonVolumeMonitor *daemon_monitor)
 
   for (l = mounts; l != NULL; l = l->next) {
     info = l->data;
-    if (info->user_visible)
-      {
-        mount = g_daemon_mount_new (info, G_VOLUME_MONITOR (daemon_monitor));
-       daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
-      }
-    
+
+    mount = g_daemon_mount_new (info, G_VOLUME_MONITOR (daemon_monitor));
+    daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
+
     g_mount_info_unref (info);
   }
   
diff --git a/common/gmounttracker.c b/common/gmounttracker.c
index 2356fe4..6789872 100644
--- a/common/gmounttracker.c
+++ b/common/gmounttracker.c
@@ -36,7 +36,8 @@ enum {
 
 enum {
   PROP_0,
-  PROP_CONNECTION
+  PROP_CONNECTION,
+  PROP_USER_VISIBLE_ONLY
 };
 
 /* TODO: Real P_() */
@@ -53,6 +54,8 @@ struct _GMountTracker
   GList *mounts;
   GDBusConnection *connection;
   GVfsDBusMountTracker *proxy;
+
+  gboolean user_visible_only;
 };
 
 G_DEFINE_TYPE (GMountTracker, g_mount_tracker, G_TYPE_OBJECT)
@@ -309,7 +312,15 @@ g_mount_tracker_class_init (GMountTrackerClass *klass)
                                                         P_("The dbus connection to use for ipc."),
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                        
G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
-  
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_USER_VISIBLE_ONLY,
+                                   g_param_spec_boolean ("user-visible-only",
+                                                         P_("User visible only"),
+                                                         P_("User visible only"),
+                                                         FALSE,
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                                         G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | 
G_PARAM_STATIC_BLURB));
 }
 
 static void
@@ -327,6 +338,9 @@ g_mount_tracker_set_property (GObject         *object,
       if (g_value_get_pointer (value))
        tracker->connection = g_object_ref (g_value_get_pointer (value));
       break;
+    case PROP_USER_VISIBLE_ONLY:
+      tracker->user_visible_only = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -346,6 +360,9 @@ g_mount_tracker_get_property (GObject    *object,
     case PROP_CONNECTION:
       g_value_set_pointer (value, tracker->connection);
       break;
+    case PROP_USER_VISIBLE_ONLY:
+      g_value_set_boolean (value, tracker->user_visible_only);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -380,6 +397,12 @@ g_mount_tracker_add_mount (GMountTracker *tracker,
       return;
     }
 
+  if (tracker->user_visible_only && !info->user_visible)
+    {
+      g_mutex_unlock (&tracker->lock);
+      return;
+    }
+
   tracker->mounts = g_list_prepend (tracker->mounts, g_mount_info_ref (info));
 
   g_mutex_unlock (&tracker->lock);
@@ -475,6 +498,7 @@ init_connection_sync (GMountTracker *tracker)
 {
   GError *error;
   GVariant *iter_mounts;
+  gboolean res;
 
   if (tracker->connection == NULL)
     tracker->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
@@ -497,7 +521,15 @@ init_connection_sync (GMountTracker *tracker)
   g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (tracker->proxy), 
                                     G_VFS_DBUS_TIMEOUT_MSECS);
 
-  if (gvfs_dbus_mount_tracker_call_list_mounts_sync (tracker->proxy, &iter_mounts, NULL, NULL))
+  res = gvfs_dbus_mount_tracker_call_list_mounts2_sync (tracker->proxy, tracker->user_visible_only, 
&iter_mounts, NULL, &error);
+  if (!res)
+    {
+      if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD))
+        res = gvfs_dbus_mount_tracker_call_list_mounts_sync (tracker->proxy, &iter_mounts, NULL, NULL);
+      g_clear_error (&error);
+    }
+
+  if (res)
     {
       list_mounts_reply (tracker, iter_mounts);
       g_variant_unref (iter_mounts);
@@ -534,12 +566,13 @@ g_mount_tracker_constructor (GType                  type,
 }
 
 GMountTracker *
-g_mount_tracker_new (GDBusConnection *connection)
+g_mount_tracker_new (GDBusConnection *connection,
+                     gboolean         user_visible_only)
 {
   GMountTracker *tracker;
 
-  tracker = g_object_new (G_TYPE_MOUNT_TRACKER, "connection", connection, NULL);
-  
+  tracker = g_object_new (G_TYPE_MOUNT_TRACKER, "connection", connection, "user_visible_only", 
user_visible_only, NULL);
+
   return tracker;
 }
 
diff --git a/common/gmounttracker.h b/common/gmounttracker.h
index cbd76f8..67ae482 100644
--- a/common/gmounttracker.h
+++ b/common/gmounttracker.h
@@ -79,7 +79,8 @@ void        g_mount_info_apply_prefix (GMountInfo *info,
 
 GMountInfo * g_mount_info_from_dbus (GVariant *value);
 
-GMountTracker *g_mount_tracker_new                (GDBusConnection *connection);
+GMountTracker *g_mount_tracker_new                (GDBusConnection *connection,
+                                                   gboolean         user_visible_only);
 GList *        g_mount_tracker_list_mounts        (GMountTracker *tracker);
 GMountInfo *   g_mount_tracker_find_by_mount_spec (GMountTracker *tracker,
                                                   GMountSpec    *mount_spec);
diff --git a/common/org.gtk.vfs.xml b/common/org.gtk.vfs.xml
index 5030bb5..5257c8a 100644
--- a/common/org.gtk.vfs.xml
+++ b/common/org.gtk.vfs.xml
@@ -82,6 +82,10 @@
     <method name="ListMounts">
       <arg type='a(sossssssbay(aya{sv})ay)' name='mounts' direction='out'/>
     </method>
+    <method name="ListMounts2">
+      <arg type='b' name='user_visible_only' direction='in'/>
+      <arg type='a(sossssssbay(aya{sv})ay)' name='mounts' direction='out'/>
+    </method>
     <method name="RegisterMount">
       <arg type='o' name='obj_path' direction='in'/>
       <arg type='s' name='display_name' direction='in'/>
diff --git a/daemon/gvfsbackendafpbrowse.c b/daemon/gvfsbackendafpbrowse.c
index 426507b..c614aee 100644
--- a/daemon/gvfsbackendafpbrowse.c
+++ b/daemon/gvfsbackendafpbrowse.c
@@ -518,7 +518,7 @@ g_vfs_backend_afp_browse_init (GVfsBackendAfpBrowse *object)
 {
   GVfsBackendAfpBrowse *afp_backend = G_VFS_BACKEND_AFP_BROWSE (object);
 
-  afp_backend->mount_tracker = g_mount_tracker_new (NULL);
+  afp_backend->mount_tracker = g_mount_tracker_new (NULL, FALSE);
 
   afp_backend->addr = NULL;
   afp_backend->user = NULL;
diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c
index ba41023..028118b 100644
--- a/daemon/gvfsbackendsmbbrowse.c
+++ b/daemon/gvfsbackendsmbbrowse.c
@@ -239,7 +239,7 @@ g_vfs_backend_smb_browse_init (GVfsBackendSmbBrowse *backend)
   g_mutex_init (&backend->update_cache_lock);
 
   if (mount_tracker == NULL)
-    mount_tracker = g_mount_tracker_new (NULL);
+    mount_tracker = g_mount_tracker_new (NULL, FALSE);
 
   /* Get default workgroup name */
   settings = g_settings_new ("org.gnome.system.smb");
diff --git a/daemon/mount.c b/daemon/mount.c
index 2e2f74b..5bab324 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -820,21 +820,51 @@ handle_lookup_mount_by_fuse_path (GVfsDBusMountTracker *object,
   return TRUE;
 }
 
+static void
+build_mounts_array (GVariantBuilder *mounts_array,
+                    gboolean user_visible_only)
+{
+  GList *l;
+  VfsMount *mount;
+
+  g_variant_builder_init (mounts_array, G_VARIANT_TYPE (VFS_MOUNT_ARRAY_DBUS_STRUCT_TYPE));
+  for (l = mounts; l != NULL; l = l->next)
+    {
+      mount = l->data;
+
+      if (!user_visible_only || mount->user_visible)
+        g_variant_builder_add_value (mounts_array, vfs_mount_to_dbus (mount));
+    }
+}
+
 static gboolean
 handle_list_mounts (GVfsDBusMountTracker *object,
                     GDBusMethodInvocation *invocation,
                     gpointer user_data)
 {
-  GList *l;
   GVariantBuilder mounts_array;
 
-  g_variant_builder_init (&mounts_array, G_VARIANT_TYPE (VFS_MOUNT_ARRAY_DBUS_STRUCT_TYPE));
-  for (l = mounts; l != NULL; l = l->next)
-    g_variant_builder_add_value (&mounts_array, vfs_mount_to_dbus (l->data));
-  
+  build_mounts_array (&mounts_array, FALSE);
+
   gvfs_dbus_mount_tracker_complete_list_mounts (object, invocation,
                                                 g_variant_builder_end (&mounts_array));
-  
+
+  return TRUE;
+}
+
+static gboolean
+handle_list_mounts2 (GVfsDBusMountTracker *object,
+                     GDBusMethodInvocation *invocation,
+                     gboolean arg_user_visible_only,
+                     gpointer user_data)
+{
+  GVariantBuilder mounts_array;
+
+  build_mounts_array (&mounts_array, arg_user_visible_only);
+
+  gvfs_dbus_mount_tracker_complete_list_mounts2 (object, invocation,
+                                                 g_variant_builder_end (&mounts_array));
+
   return TRUE;
 }
 
@@ -1056,6 +1086,7 @@ mount_init (void)
   g_signal_connect (mount_tracker, "handle-lookup-mount", G_CALLBACK (handle_lookup_mount), NULL);
   g_signal_connect (mount_tracker, "handle-lookup-mount-by-fuse-path", G_CALLBACK 
(handle_lookup_mount_by_fuse_path), NULL);
   g_signal_connect (mount_tracker, "handle-list-mounts", G_CALLBACK (handle_list_mounts), NULL);
+  g_signal_connect (mount_tracker, "handle-list-mounts2", G_CALLBACK (handle_list_mounts2), NULL);
   g_signal_connect (mount_tracker, "handle-list-mountable-info", G_CALLBACK (handle_list_mountable_info), 
NULL);
   g_signal_connect (mount_tracker, "handle-list-mount-types", G_CALLBACK (handle_list_mount_types), NULL);
   g_signal_connect (mount_tracker, "handle-unregister-mount", G_CALLBACK (handle_unregister_mount), NULL);


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