aboutsummaryrefslogtreecommitdiff
path: root/devel/gnome-vfs/files/patch-libgnomevfs_gnome-vfs-monitor.c
blob: 11d73973b413f3258aafba06ae732f46b19f8b06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
--- 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);