summaryrefslogtreecommitdiff
path: root/libnautilus-private
diff options
context:
space:
mode:
authorRazvan Chitu <razvan.ch95@gmail.com>2016-03-14 11:18:55 +0200
committerRazvan Chitu <razvan.ch95@gmail.com>2016-04-08 00:13:44 +0300
commita99b4cf8f1163a2ef8a6cd1d713482978deebf7b (patch)
tree5362246d0b2e50a4e4f90d7b9748c8ab099d43ab /libnautilus-private
parent0e3ebc7cdbba0df6673c3ba1ee1c2fc26d11f8f5 (diff)
downloadnautilus-a99b4cf8f1163a2ef8a6cd1d713482978deebf7b.tar.gz
trash-monitor: change trash monitoring process
In Nautilus, the trash is monitored for state changes - going from empty to non-empty and the other way round. Monitoring is done by handling change signals from a regular file monitor. On each signal, an enumeration of the trash contents is started in order to see if it is empty or not. This causes issues when many files are trashed, because the gvfs trash backend is flooded with enumeration requests, resulting in CPU usage spikes. In order to fix this, the "item-count" attribute of the trash should be queried instead. Replace asynchronous enumeration with asynchronous information query and update the trash state based on the "item-count" attribute. https://bugzilla.gnome.org/show_bug.cgi?id=763218
Diffstat (limited to 'libnautilus-private')
-rw-r--r--libnautilus-private/nautilus-trash-monitor.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/libnautilus-private/nautilus-trash-monitor.c b/libnautilus-private/nautilus-trash-monitor.c
index 695b87e82..fd26421aa 100644
--- a/libnautilus-private/nautilus-trash-monitor.c
+++ b/libnautilus-private/nautilus-trash-monitor.c
@@ -97,44 +97,35 @@ update_empty_info (NautilusTrashMonitor *trash_monitor,
trash_monitor->details->empty);
}
+/* Use G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT since we only want to know whether the
+ * trash is empty or not, not access its children. This is available for the
+ * trash backend since it uses a cache. In this way we prevent flooding the
+ * trash backend with enumeration requests when trashing > 1000 files
+ */
static void
-enumerate_next_files_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
+trash_query_info_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
- NautilusTrashMonitor *trash_monitor = user_data;
- GList *infos;
-
- infos = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source), res, NULL);
- if (!infos) {
- update_empty_info (trash_monitor, TRUE);
- } else {
- update_empty_info (trash_monitor, FALSE);
- g_list_free_full (infos, g_object_unref);
- }
+ NautilusTrashMonitor *trash_monitor = user_data;
+ GFileInfo *info;
+ guint32 item_count;
+ gboolean is_empty = TRUE;
- g_object_unref (trash_monitor);
-}
+ info = g_file_query_info_finish (G_FILE (source), res, NULL);
-static void
-enumerate_children_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- GFileEnumerator *enumerator;
- NautilusTrashMonitor *trash_monitor = user_data;
+ if (info != NULL) {
+ item_count = g_file_info_get_attribute_uint32 (info,
+ G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT);
+ is_empty = item_count == 0;
- enumerator = g_file_enumerate_children_finish (G_FILE (source), res, NULL);
- if (!enumerator) {
- update_empty_info (trash_monitor, TRUE);
- g_object_unref (trash_monitor);
- return;
- }
+ g_object_unref (info);
+
+ }
+
+ update_empty_info (trash_monitor, is_empty);
- g_file_enumerator_next_files_async (enumerator, 1,
- G_PRIORITY_DEFAULT, NULL,
- enumerate_next_files_cb, trash_monitor);
- g_object_unref (enumerator);
+ g_object_unref (trash_monitor);
}
static void
@@ -143,11 +134,11 @@ schedule_update_info (NautilusTrashMonitor *trash_monitor)
GFile *location;
location = g_file_new_for_uri ("trash:///");
- g_file_enumerate_children_async (location,
- G_FILE_ATTRIBUTE_STANDARD_TYPE,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT, NULL,
- enumerate_children_cb, g_object_ref (trash_monitor));
+ g_file_query_info_async (location,
+ G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT,
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT, NULL,
+ trash_query_info_cb, g_object_ref (trash_monitor));
g_object_unref (location);
}