glib r6584 - trunk/gio
- From: alexl svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r6584 - trunk/gio
- Date: Mon, 25 Feb 2008 12:34:30 +0000 (GMT)
Author: alexl
Date: Mon Feb 25 12:34:30 2008
New Revision: 6584
URL: http://svn.gnome.org/viewvc/glib?rev=6584&view=rev
Log:
2008-02-25 Alexander Larsson <alexl redhat com>
* gfilemonitor.c:
Emit actual change signals in an idle handler.
This avoids reentrance and locking problems in
the file notification backends.
Modified:
trunk/gio/ChangeLog
trunk/gio/gfilemonitor.c
Modified: trunk/gio/gfilemonitor.c
==============================================================================
--- trunk/gio/gfilemonitor.c (original)
+++ trunk/gio/gfilemonitor.c Mon Feb 25 12:34:30 2008
@@ -302,6 +302,60 @@
}
}
+typedef struct {
+ GFileMonitor *monitor;
+ 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);
+
+ g_slice_free (FileChange, change);
+}
+
+static void
+emit_in_idle (GFileMonitor *monitor,
+ GFile *child,
+ GFile *other_file,
+ GFileMonitorEvent event_type)
+{
+ GSource *source;
+ FileChange *change;
+
+ 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);
+ else
+ change->other_file = NULL;
+ change->event_type = event_type;
+
+ source = g_idle_source_new ();
+ g_source_set_priority (source, 0);
+
+ g_source_set_callback (source, emit_cb, change, file_change_free);
+ g_source_attach (source, NULL);
+ g_source_unref (source);
+}
+
static guint32
get_time_msecs (void)
{
@@ -337,9 +391,8 @@
{
if (limiter->send_virtual_changes_done_at != 0)
{
- g_signal_emit (monitor, signals[CHANGED], 0,
- limiter->file, NULL,
- G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
+ emit_in_idle (monitor, limiter->file, NULL,
+ G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
limiter->send_virtual_changes_done_at = 0;
}
}
@@ -351,9 +404,9 @@
{
if (limiter->send_delayed_change_at != 0)
{
- g_signal_emit (monitor, signals[CHANGED], 0,
- limiter->file, NULL,
- G_FILE_MONITOR_EVENT_CHANGED);
+ emit_in_idle (monitor,
+ limiter->file, NULL,
+ G_FILE_MONITOR_EVENT_CHANGED);
limiter->send_delayed_change_at = 0;
limiter->last_sent_change_time = time_now;
}
@@ -522,6 +575,8 @@
* Emits the #GFileMonitor::changed signal if a change
* has taken place. Should be called from file monitor
* implementations only.
+ *
+ * The signal will be emitted from an idle handler.
**/
void
g_file_monitor_emit_event (GFileMonitor *monitor,
@@ -549,7 +604,7 @@
rate_limiter_send_virtual_changes_done_now (monitor, limiter);
update_rate_limiter_timeout (monitor, 0);
}
- g_signal_emit (monitor, signals[CHANGED], 0, child, other_file, event_type);
+ emit_in_idle (monitor, child, other_file, event_type);
}
else
{
@@ -578,7 +633,7 @@
if (emit_now)
{
- g_signal_emit (monitor, signals[CHANGED], 0, child, other_file, event_type);
+ emit_in_idle (monitor, child, other_file, event_type);
limiter->last_sent_change_time = time_now;
limiter->send_delayed_change_at = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]