glib r8010 - trunk/gio
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r8010 - trunk/gio
- Date: Tue, 17 Mar 2009 21:59:18 +0000 (UTC)
Author: walters
Date: Tue Mar 17 21:59:18 2009
New Revision: 8010
URL: http://svn.gnome.org/viewvc/glib?rev=8010&view=rev
Log:
2009-03-17 Colin Walters <walters redhat com>
Bug 575708 - runaway inotify madness ...
* gfilemonitor.c: Queue up events in a local list and
fire one idle, instead of queuing lots of individual
idles which has bad performance behavior.
Modified:
trunk/gio/ChangeLog
trunk/gio/gfilemonitor.c
Modified: trunk/gio/gfilemonitor.c
==============================================================================
--- trunk/gio/gfilemonitor.c (original)
+++ trunk/gio/gfilemonitor.c Tue Mar 17 21:59:18 2009
@@ -32,6 +32,10 @@
#include "gioalias.h"
+struct _FileChange;
+typedef struct _FileChange FileChange;
+static void file_change_free (FileChange *change);
+
/**
* SECTION:gfilemonitor
* @short_description: File Monitor
@@ -73,6 +77,9 @@
/* Rate limiting change events */
GHashTable *rate_limiter;
+ guint pending_file_change_id;
+ GSList *pending_file_changes; /* FileChange */
+
GSource *timeout;
guint32 timeout_fires_at;
};
@@ -169,8 +176,19 @@
g_file_monitor_dispose (GObject *object)
{
GFileMonitor *monitor;
+ GFileMonitorPrivate *priv;
monitor = G_FILE_MONITOR (object);
+ priv = monitor->priv;
+
+ if (priv->pending_file_change_id)
+ {
+ g_source_remove (priv->pending_file_change_id);
+ priv->pending_file_change_id = 0;
+ }
+ g_slist_foreach (priv->pending_file_changes, (GFunc) file_change_free, NULL);
+ g_slist_free (priv->pending_file_changes);
+ priv->pending_file_changes = NULL;
/* Make sure we cancel on last unref */
g_file_monitor_cancel (monitor);
@@ -320,26 +338,15 @@
}
}
-typedef struct {
- GFileMonitor *monitor;
+struct _FileChange {
GFile *child;
GFile *other_file;
GFileMonitorEvent event_type;
-} FileChange;
-
-static gboolean
-emit_cb (gpointer data)
-{
- FileChange *change = data;
- g_signal_emit (change->monitor, signals[CHANGED], 0,
- change->child, change->other_file, change->event_type);
- return FALSE;
-}
+};
static void
file_change_free (FileChange *change)
{
- g_object_unref (change->monitor);
g_object_unref (change->child);
if (change->other_file)
g_object_unref (change->other_file);
@@ -347,6 +354,27 @@
g_slice_free (FileChange, change);
}
+static gboolean
+emit_cb (gpointer data)
+{
+ GFileMonitor *monitor = G_FILE_MONITOR (data);
+ GSList *pending, *iter;
+
+ pending = g_slist_reverse (monitor->priv->pending_file_changes);
+ monitor->priv->pending_file_changes = NULL;
+ monitor->priv->pending_file_change_id = 0;
+
+ for (iter = pending; iter; iter = iter->next)
+ {
+ FileChange *change = iter->data;
+ g_signal_emit (monitor, signals[CHANGED], 0,
+ change->child, change->other_file, change->event_type);
+ file_change_free (change);
+ }
+ g_slist_free (pending);
+ return FALSE;
+}
+
static void
emit_in_idle (GFileMonitor *monitor,
GFile *child,
@@ -355,10 +383,12 @@
{
GSource *source;
FileChange *change;
+ GFileMonitorPrivate *priv;
+
+ priv = monitor->priv;
change = g_slice_new (FileChange);
- change->monitor = g_object_ref (monitor);
change->child = g_object_ref (child);
if (other_file)
change->other_file = g_object_ref (other_file);
@@ -366,12 +396,20 @@
change->other_file = NULL;
change->event_type = event_type;
- source = g_idle_source_new ();
- g_source_set_priority (source, 0);
+ if (!priv->pending_file_change_id)
+ {
+ source = g_idle_source_new ();
+ g_source_set_priority (source, 0);
- g_source_set_callback (source, emit_cb, change, (GDestroyNotify)file_change_free);
- g_source_attach (source, NULL);
- g_source_unref (source);
+ /* We don't ref here - instead dispose will free any
+ * pending idles.
+ */
+ g_source_set_callback (source, emit_cb, monitor, NULL);
+ priv->pending_file_change_id = g_source_attach (source, NULL);
+ g_source_unref (source);
+ }
+ /* We reverse this in the processor */
+ priv->pending_file_changes = g_slist_prepend (priv->pending_file_changes, change);
}
static guint32
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]