[gtk/matthiasc/for-master] trash-monitor: Rate limit updates
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/for-master] trash-monitor: Rate limit updates
- Date: Fri, 22 May 2020 01:16:07 +0000 (UTC)
commit e8a120e5afd4542584ecbbe23f76300d2c858d9e
Author: Ondrej Holy <oholy redhat com>
Date: Thu May 21 21:14:47 2020 -0400
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...
Fixes: #1010
gtk/gtktrashmonitor.c | 69 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 55 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtktrashmonitor.c b/gtk/gtktrashmonitor.c
index d52006432e..fe9d3fcb98 100644
--- a/gtk/gtktrashmonitor.c
+++ b/gtk/gtktrashmonitor.c
@@ -24,13 +24,18 @@
#include "gtkmarshalers.h"
#include "gtktrashmonitor.h"
+#define UPDATE_RATE_SECONDS 1
+
struct _GtkTrashMonitor
{
GObject parent;
GFileMonitor *file_monitor;
gulong file_monitor_changed_id;
-
+
+ gboolean pending;
+ gint timeout_id;
+
guint has_trash : 1;
};
@@ -70,6 +75,10 @@ gtk_trash_monitor_dispose (GObject *object)
g_clear_object (&monitor->file_monitor);
}
+ if (monitor->timeout_id > 0)
+ g_source_remove (monitor->timeout_id);
+ monitor->timeout_id = 0;
+
G_OBJECT_CLASS (_gtk_trash_monitor_parent_class)->dispose (object);
}
@@ -84,18 +93,18 @@ _gtk_trash_monitor_class_init (GtkTrashMonitorClass *class)
signals[TRASH_STATE_CHANGED] =
g_signal_new (I_("trash-state-changed"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkTrashMonitorClass, trash_state_changed),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkTrashMonitorClass, trash_state_changed),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
}
/* Updates the internal has_trash flag and emits the "trash-state-changed" signal */
static void
update_has_trash_and_notify (GtkTrashMonitor *monitor,
- gboolean has_trash)
+ gboolean has_trash)
{
if (monitor->has_trash == !!has_trash)
return;
@@ -136,12 +145,38 @@ trash_query_info_cb (GObject *source,
g_object_unref (monitor); /* was reffed in recompute_trash_state() */
}
+static void recompute_trash_state (GtkTrashMonitor *monitor);
+
+static gboolean
+recompute_trash_state_cb (gpointer data)
+{
+ GtkTrashMonitor *monitor = data;
+
+ monitor->timeout_id = 0;
+ if (monitor->pending)
+ {
+ monitor->pending = FALSE;
+ recompute_trash_state (monitor);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
/* Asynchronously recomputes whether there is trash or not */
static void
recompute_trash_state (GtkTrashMonitor *monitor)
{
GFile *file;
+ /* Rate limit the updates to not flood the gvfsd-trash when too many changes
+ * happended in a short time.
+ */
+ if (monitor->timeout_id > 0)
+ {
+ monitor->pending = TRUE;
+ return;
+ }
+
file = g_file_new_for_uri ("trash:///");
g_file_query_info_async (file,
G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT,
@@ -149,6 +184,10 @@ recompute_trash_state (GtkTrashMonitor *monitor)
G_PRIORITY_DEFAULT, NULL,
trash_query_info_cb, g_object_ref (monitor));
+ monitor->timeout_id = g_timeout_add_seconds (UPDATE_RATE_SECONDS,
+ recompute_trash_state_cb,
+ monitor);
+
g_object_unref (file);
}
@@ -156,11 +195,11 @@ recompute_trash_state (GtkTrashMonitor *monitor)
* whenever something happens.
*/
static void
-file_monitor_changed_cb (GFileMonitor *file_monitor,
- GFile *child,
- GFile *other_file,
- GFileMonitorEvent event_type,
- GtkTrashMonitor *monitor)
+file_monitor_changed_cb (GFileMonitor *file_monitor,
+ GFile *child,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ GtkTrashMonitor *monitor)
{
recompute_trash_state (monitor);
}
@@ -173,12 +212,14 @@ _gtk_trash_monitor_init (GtkTrashMonitor *monitor)
file = g_file_new_for_uri ("trash:///");
monitor->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ monitor->pending = FALSE;
+ monitor->timeout_id = 0;
g_object_unref (file);
if (monitor->file_monitor)
monitor->file_monitor_changed_id = g_signal_connect (monitor->file_monitor, "changed",
- G_CALLBACK (file_monitor_changed_cb), monitor);
+ G_CALLBACK (file_monitor_changed_cb), monitor);
recompute_trash_state (monitor);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]