summaryrefslogblamecommitdiffstats
path: root/devel/gnome-vfs/files/patch-libgnomevfs_gnome-vfs-monitor.c
blob: 11d73973b413f3258aafba06ae732f46b19f8b06 (plain) (tree)


































































































































                                                                                                                           
--- libgnomevfs/gnome-vfs-monitor.c.orig    Fri May 12 20:46:39 2006
+++ libgnomevfs/gnome-vfs-monitor.c Fri May 12 22:29:57 2006
@@ -48,9 +48,6 @@
    
    GList *pending_callbacks; /* protected by handle_hash */
    guint pending_timeout; /* protected by handle_hash */
-   guint timeout_count; /* count up each time pending_timeout is changed
-               to avoid timeout remove race.
-               protected by handle_hash */
 };
 
 struct GnomeVFSMonitorCallbackData {
@@ -69,6 +66,9 @@
 static GHashTable *handle_hash = NULL;
 G_LOCK_DEFINE_STATIC (handle_hash);
 
+static gint actually_dispatch_callback (gpointer data);
+static guint32 get_min_delay  (GList *list, gint32 now);
+
 static void 
 init_hash_table (void)
 {
@@ -202,17 +202,25 @@
    return result;
 }
 
+static void
+install_timeout (GnomeVFSMonitorHandle *monitor_handle, time_t now)
+{
+   guint32 delay;
 
-typedef struct {
-   guint timeout_count;
-   GnomeVFSMonitorHandle *monitor_handle;
-} DispatchData;
+   if (monitor_handle->pending_timeout) 
+       g_source_remove (monitor_handle->pending_timeout);
+
+   delay = get_min_delay (monitor_handle->pending_callbacks, now);
+   if (delay == 0)
+       monitor_handle->pending_timeout = g_idle_add (actually_dispatch_callback, monitor_handle);
+   else
+       monitor_handle->pending_timeout = g_timeout_add (delay * 1000, actually_dispatch_callback, monitor_handle);
+}
 
 static gint
 actually_dispatch_callback (gpointer data)
 {
-   DispatchData *ddata = data;
-   GnomeVFSMonitorHandle *monitor_handle = ddata->monitor_handle;
+   GnomeVFSMonitorHandle *monitor_handle = data;
    GnomeVFSMonitorCallbackData *callback_data;
    gchar *uri;
    GList *l, *next;
@@ -228,13 +236,6 @@
 
    G_LOCK (handle_hash);
 
-   /* Don't clear pending_timeout if we started another timeout
-    * (and removed this)
-    */
-   if (monitor_handle->timeout_count == ddata->timeout_count) {
-       monitor_handle->pending_timeout = 0;
-   }
-
    if (!monitor_handle->cancelled) {
        /* Find all callbacks that needs to be dispatched */
        dispatch = NULL;
@@ -305,13 +306,17 @@
 
    }
 
-   /* if we were waiting for this callback to be dispatched to free
-    * this monitor, then do it now.
-    */
-   if (monitor_handle->cancelled &&
-       no_live_callbacks (monitor_handle)) {
-       destroy_monitor_handle (monitor_handle);
-   }
+   if (no_live_callbacks (monitor_handle)) {
+       /* if we were waiting for this callback to be dispatched
+        * to free this monitor, then do it now.
+        */
+       if (monitor_handle->cancelled)
+           destroy_monitor_handle (monitor_handle);
+       else
+           monitor_handle->pending_timeout = 0;
+   } else
+       /* pending callbacks left, install another timeout */
+       install_timeout (monitor_handle, now);
 
    G_UNLOCK (handle_hash);
 
@@ -375,9 +380,7 @@
    GnomeVFSMonitorHandle *monitor_handle;
    char *uri;
    time_t now;
-   guint32 delay;
    GList *l;
-   DispatchData *ddata;
    
    g_return_if_fail (info_uri != NULL);
 
@@ -435,26 +438,7 @@
        monitor_handle->pending_callbacks = 
            g_list_append(monitor_handle->pending_callbacks, callback_data);
        
-       delay = get_min_delay (monitor_handle->pending_callbacks, now);
-
-       if (monitor_handle->pending_timeout) {
-           g_source_remove (monitor_handle->pending_timeout);
-       }
-       
-       ddata = g_new (DispatchData, 1);
-       ddata->monitor_handle = monitor_handle;
-       ddata->timeout_count = ++monitor_handle->timeout_count;
-       
-       if (delay == 0) {
-           monitor_handle->pending_timeout = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
-                                      actually_dispatch_callback,
-                                      ddata, (GDestroyNotify)g_free);
-       } else {
-           monitor_handle->pending_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT,
-                                         delay * 1000,
-                                         actually_dispatch_callback,
-                                         ddata, (GDestroyNotify)g_free);
-       }
+       install_timeout (monitor_handle, now);
    }
    
    g_free (uri);