summaryrefslogtreecommitdiff
path: root/src/nautilus-trash-monitor.c
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2018-01-05 16:06:40 +0100
committerOndrej Holy <oholy@redhat.com>2018-01-08 18:24:42 +0100
commit3ccd29e13c7e0058706060470cbcfea0f3310b6e (patch)
treeec35d91c1057e1582b079fd4bf086ca1141d7cd7 /src/nautilus-trash-monitor.c
parent5fe3422fefde027e526d866f612b70d860037c73 (diff)
downloadnautilus-3ccd29e13c7e0058706060470cbcfea0f3310b6e.tar.gz
trash-monitor: Rate limit updates
Trash monitor queries info from gvfsd-trash after each file monitor change which can be problematic when too many changes happen in a short time. Let's rate limit the number of queries...
Diffstat (limited to 'src/nautilus-trash-monitor.c')
-rw-r--r--src/nautilus-trash-monitor.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/nautilus-trash-monitor.c b/src/nautilus-trash-monitor.c
index 318926f80..97f487409 100644
--- a/src/nautilus-trash-monitor.c
+++ b/src/nautilus-trash-monitor.c
@@ -29,10 +29,14 @@
#include <gio/gio.h>
#include <string.h>
+#define UPDATE_RATE_SECONDS 5
+
struct NautilusTrashMonitorDetails
{
gboolean empty;
GFileMonitor *file_monitor;
+ gboolean pending;
+ gint timeout_id;
};
enum
@@ -53,6 +57,12 @@ nautilus_trash_monitor_finalize (GObject *object)
trash_monitor = NAUTILUS_TRASH_MONITOR (object);
+ if (trash_monitor->details->timeout_id > 0)
+ {
+ g_source_remove (trash_monitor->details->timeout_id);
+ trash_monitor->details->timeout_id = 0;
+ }
+
if (trash_monitor->details->file_monitor)
{
g_object_unref (trash_monitor->details->file_monitor);
@@ -131,11 +141,37 @@ trash_query_info_cb (GObject *source,
g_object_unref (trash_monitor);
}
+static void schedule_update_info (NautilusTrashMonitor *trash_monitor);
+
+static gboolean
+schedule_update_info_cb (gpointer data)
+{
+ NautilusTrashMonitor *trash_monitor = data;
+
+ trash_monitor->details->timeout_id = 0;
+ if (trash_monitor->details->pending)
+ {
+ trash_monitor->details->pending = FALSE;
+ schedule_update_info (trash_monitor);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
static void
schedule_update_info (NautilusTrashMonitor *trash_monitor)
{
GFile *location;
+ /* Rate limit the updates to not flood the gvfsd-trash when too many changes
+ * happended in a short time.
+ */
+ if (trash_monitor->details->timeout_id > 0)
+ {
+ trash_monitor->details->pending = TRUE;
+ return;
+ }
+
location = g_file_new_for_uri ("trash:///");
g_file_query_info_async (location,
G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT,
@@ -143,6 +179,9 @@ schedule_update_info (NautilusTrashMonitor *trash_monitor)
G_PRIORITY_DEFAULT, NULL,
trash_query_info_cb, g_object_ref (trash_monitor));
+ trash_monitor->details->timeout_id = g_timeout_add_seconds (UPDATE_RATE_SECONDS,
+ schedule_update_info_cb,
+ trash_monitor);
g_object_unref (location);
}
@@ -174,6 +213,8 @@ nautilus_trash_monitor_init (NautilusTrashMonitor *trash_monitor)
location = g_file_new_for_uri ("trash:///");
trash_monitor->details->file_monitor = g_file_monitor_file (location, 0, NULL, NULL);
+ trash_monitor->details->pending = FALSE;
+ trash_monitor->details->timeout_id = 0;
g_signal_connect (trash_monitor->details->file_monitor, "changed",
(GCallback) file_changed, trash_monitor);