diff options
author | Ondrej Holy <oholy@redhat.com> | 2017-01-04 10:31:08 +0100 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2017-06-06 09:11:24 +0200 |
commit | ceb0daa48bd6b5144873a4984572c2781fa4a7ac (patch) | |
tree | 3ef72406e6e921caa0ba7441b6b08c2d8ec6708e | |
parent | 29872122c87623c77a85869e309f79a50aed8e09 (diff) | |
download | gvfs-ceb0daa48bd6b5144873a4984572c2781fa4a7ac.tar.gz |
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
-rw-r--r-- | client/gdaemonvolumemonitor.c | 26 | ||||
-rw-r--r-- | common/gmounttracker.c | 45 | ||||
-rw-r--r-- | common/gmounttracker.h | 3 | ||||
-rw-r--r-- | common/org.gtk.vfs.xml | 4 | ||||
-rw-r--r-- | daemon/gvfsbackendafpbrowse.c | 2 | ||||
-rw-r--r-- | daemon/gvfsbackendsmbbrowse.c | 2 | ||||
-rw-r--r-- | daemon/mount.c | 43 |
7 files changed, 94 insertions, 31 deletions
diff --git a/client/gdaemonvolumemonitor.c b/client/gdaemonvolumemonitor.c index b73453b2..dc1407d2 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 2356fe40..67898728 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 cbd76f8b..67ae4828 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 5030bb5f..5257c8a7 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 426507b5..c614aeeb 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 ba410237..028118bb 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 2e2f74b0..5bab324d 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); |