+struct _FileChange {
+ GFile *child;
+ GFile *other_file;
+ GFileMonitorEvent event_type;
+};
+
+static void
+file_change_free (FileChange *change)
+{
+ g_object_unref (change->child);
+ if (change->other_file)
+ g_object_unref (change->other_file);
+
+ g_slice_free (FileChange, change);
+}
+
+static gboolean
+emit_cb (gpointer data)
+{
+ GFileMonitor *monitor = G_FILE_MONITOR (data);
+ GSList *pending, *iter;
+
+ g_mutex_lock (&monitor->priv->mutex);
+ pending = g_slist_reverse (monitor->priv->pending_file_changes);
+ monitor->priv->pending_file_changes = NULL;
+ if (monitor->priv->pending_file_change_source)
+ {
+ g_source_unref (monitor->priv->pending_file_change_source);
+ monitor->priv->pending_file_change_source = NULL;
+ }
+ g_mutex_unlock (&monitor->priv->mutex);
+
+ g_object_ref (monitor);
+ 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);
+ g_object_unref (monitor);
+
+ return FALSE;
+}
+
+static void
+emit_in_idle (GFileMonitor *monitor,
+ GFile *child,
+ GFile *other_file,
+ GFileMonitorEvent event_type)
+{
+ GSource *source;
+ FileChange *change;
+ GFileMonitorPrivate *priv;
+
+ priv = monitor->priv;
+
+ change = g_slice_new (FileChange);
+
+ change->child = g_object_ref (child);
+ if (other_file)
+ change->other_file = g_object_ref (other_file);
+ else
+ change->other_file = NULL;
+ change->event_type = event_type;
+
+ g_mutex_lock (&monitor->priv->mutex);
+ if (!priv->pending_file_change_source)
+ {
+ source = g_idle_source_new ();
+ priv->pending_file_change_source = source;
+ g_source_set_priority (source, 0);
+
+ /* We don't ref monitor here - instead dispose will free any
+ * pending idles.
+ */
+ g_source_set_callback (source, emit_cb, monitor, NULL);
+ g_source_set_name (source, "[gio] emit_cb");
+ g_source_attach (source, monitor->priv->context);
+ }
+ /* We reverse this in the processor */
+ priv->pending_file_changes = g_slist_prepend (priv->pending_file_changes, change);
+ g_mutex_unlock (&monitor->priv->mutex);
+}
+