[gamin] poll-loop rework patch



Yo,

So I spent a few hours trying to get this to work, but I'm not going to
put anymore effort into it right now. I'm posting this in case someone
wants to pick up where I left off. 

The patch tries to fix the for loops in gam_poll_dnotify_scan_callback
so that they can just walk the list. To accomplish this, I added
X_to_remove and X_to_add lists for missing/busy/all resource lists. Then
I processed this lists before walking the lists in
gam_poll_dnotify_scan_callback. This sort of worked, and a lot of the
test suite passes, but there seems to be some expectation that when
gam_poll_remove_* is called, that the node is actually off the list.
It's just a matter of sorting this stuff out. 

-- 
John McCutchan <ttb tentacle dhs org>
Index: server/gam_poll_dnotify.c
===================================================================
RCS file: /cvs/gnome/gamin/server/gam_poll_dnotify.c,v
retrieving revision 1.1
diff -u -r1.1 gam_poll_dnotify.c
--- server/gam_poll_dnotify.c	15 Aug 2005 19:34:58 -0000	1.1
+++ server/gam_poll_dnotify.c	15 Aug 2005 21:52:30 -0000
@@ -43,6 +43,8 @@
 static GaminEventType gam_poll_dnotify_poll_file(GamNode * node);
 static gboolean gam_poll_dnotify_scan_callback(gpointer data);
 
+#define VERBOSE_POLL
+#define VERBOSE_POLL2
 
 gboolean
 gam_poll_dnotify_init ()
@@ -195,7 +197,7 @@
     }
 
 #ifdef VERBOSE_POLL
-    GAM_DEBUG(DEBUG_INFO, " at %d delta %d : %d\n", current_time, current_time - node->lasttime, node->checks);
+    GAM_DEBUG(DEBUG_INFO, " at %d delta %d : %d\n", gam_poll_generic_get_time(), gam_poll_generic_get_time() - node->lasttime, node->checks);
 #endif
 
     event = 0;
@@ -418,8 +420,7 @@
         if ((!gam_node_get_subscriptions(child)) && (remove_dir) &&
             (!gam_tree_has_children(gam_poll_generic_get_tree(), child))) {
             gam_poll_generic_unregister_node (child);
-
-            gam_tree_remove(gam_poll_generic_get_tree(), child);
+			gam_poll_generic_remove_from_tree (child);
         } else {
             remove_dir = FALSE;
         }
@@ -548,7 +549,7 @@
                     parent = gam_node_parent(node);
                     if ((parent != NULL) &&
                         (!gam_node_has_dir_subscriptions(parent))) {
-                        gam_tree_remove(gam_poll_generic_get_tree(), node);
+						gam_poll_generic_remove_from_tree (node);
 
                         gam_poll_generic_prune_tree(parent);
                     }
@@ -563,7 +564,7 @@
                 gam_poll_generic_unregister_node (node);
                 parent = gam_node_parent(node);
                 if (!gam_tree_has_children(gam_poll_generic_get_tree(), node)) {
-                    gam_tree_remove(gam_poll_generic_get_tree(), node);
+					gam_poll_generic_remove_from_tree (node);
                 }
 
                 gam_poll_generic_prune_tree(parent);
@@ -633,99 +634,81 @@
 static gboolean
 gam_poll_dnotify_scan_callback(gpointer data)
 {
-    int idx;
-    static int in_poll_callback = 0;
+	GList *l = NULL;
 
 #ifdef VERBOSE_POLL
-    GAM_DEBUG(DEBUG_INFO, "gam_poll_scan_callback(): %d, %d missing, %d busy\n", in_poll_callback, g_list_length(missing_resources), g_list_length(busy_resources));
+    GAM_DEBUG(DEBUG_INFO, "gam_poll_scan_callback(): %d missing, %d busy\n", g_list_length(gam_poll_generic_get_missing_list()), g_list_length(gam_poll_generic_get_busy_list()));
 #endif
-    if (in_poll_callback)
-        return TRUE;
-
-    in_poll_callback++;
 
 	gam_poll_generic_update_time ();
 
-    for (idx = 0;; idx++)
-    {
-        GamNode *node;
+	gam_poll_generic_flush_node_queues();
 
-        /*
-         * do not simply walk the list as it may be modified in the callback
-         */
-        node = (GamNode *) g_list_nth_data(gam_poll_generic_get_missing_list(), idx);
-
-        if (node == NULL) {
-#ifdef VERBOSE_POLL2
-            GAM_DEBUG(DEBUG_INFO, "missing list node %d == NULL\n", idx);
-#endif
-            break;
-        }
+	l = gam_poll_generic_get_missing_list ();
+	while (l) 
+	{
+		GamNode *node = l->data;
+		g_assert (node);
 #ifdef VERBOSE_POLL
-        GAM_DEBUG(DEBUG_INFO, "Checking missing file %s", node->path);
+		GAM_DEBUG(DEBUG_INFO, "Checking missing file %s", node->path);
 #endif
-        if (node->is_dir) {
-            gam_poll_generic_scan_directory_internal(node);
-        } else {
-            GaminEventType event;
-
-            event = gam_poll_dnotify_poll_file (node);
-            gam_node_emit_event(node, event);
-        }
-
-        /*
-         * if the resource exists again and is not in a special monitoring
-         * mode then switch back to dnotify for monitoring.
-         */
-        if (!gam_node_has_pflags (node, MON_ALL_PFLAGS) && (!gam_exclude_check(node->path) && gam_fs_get_mon_type (node->path) == GFS_MT_KERNEL))
-        {
-            gam_poll_generic_remove_missing(node);
-            if (gam_node_get_subscriptions(node) != NULL) {
-                gam_poll_dnotify_relist_node(node);
-            }
-        }
-    }
 
-    for (idx = 0;; idx++)
-    {
-        GamNode *node;
+		if (node->is_dir) {
+			gam_poll_generic_scan_directory_internal(node);
+		} else {
+			GaminEventType event;
+
+			event = gam_poll_dnotify_poll_file (node);
+			gam_node_emit_event(node, event);
+		}
+
+		/*
+		* if the resource exists again and is not in a special monitoring
+		* mode then switch back to dnotify for monitoring.
+		*/
+		if (!gam_node_has_pflags (node, MON_ALL_PFLAGS) && (!gam_exclude_check(node->path) && gam_fs_get_mon_type (node->path) == GFS_MT_KERNEL))
+		{
+			gam_poll_generic_remove_missing(node);
+			if (gam_node_get_subscriptions(node) != NULL) 
+			{
+				gam_poll_dnotify_relist_node(node);
+			}
+		}
 
-        /*
-        * do not simply walk the list as it may be modified in the callback
-        */
-        node = (GamNode *) g_list_nth_data(gam_poll_generic_get_busy_list(), idx);
+		l = l->next;
+	}
 
-        if (node == NULL)
-        {
-#ifdef VERBOSE_POLL2
-            GAM_DEBUG(DEBUG_INFO, "busy list node %d == NULL\n", idx);
-#endif
-            break;
-        }
+	l = gam_poll_generic_get_busy_list ();
+	while (l) 
+	{
+		GamNode *node = l->data;
+		g_assert (node);
 #ifdef VERBOSE_POLL
-        GAM_DEBUG(DEBUG_INFO, "Checking busy file %s", node->path);
+		GAM_DEBUG(DEBUG_INFO, "Checking busy file %s", node->path);
 #endif
-        if (node->is_dir) {
-            gam_poll_generic_scan_directory_internal(node);
-        } else {
-            GaminEventType event;
+		if (node->is_dir) {
+			gam_poll_generic_scan_directory_internal(node);
+		} else {
+			GaminEventType event;
+
+			event = gam_poll_dnotify_poll_file (node);
+			gam_node_emit_event(node, event);
+		}
+
+		/*
+		* if the resource exists again and is not in a special monitoring
+		* mode then switch back to dnotify for monitoring.
+		*/
+		if (!gam_node_has_pflags (node, MON_ALL_PFLAGS) && (!gam_exclude_check(node->path) && gam_fs_get_mon_type (node->path) == GFS_MT_KERNEL))
+		{
+			gam_poll_generic_remove_busy(node);
+			if (gam_node_get_subscriptions(node) != NULL) {
+				gam_poll_dnotify_flowoff_node(node);
+			}
+		}
 
-            event = gam_poll_dnotify_poll_file (node);
-            gam_node_emit_event(node, event);
-        }
+		l = l->next;
+	}
 
-        /*
-        * if the resource exists again and is not in a special monitoring
-        * mode then switch back to dnotify for monitoring.
-        */
-        if (!gam_node_has_pflags (node, MON_ALL_PFLAGS) && (!gam_exclude_check(node->path) && gam_fs_get_mon_type (node->path) == GFS_MT_KERNEL))
-        {
-            gam_poll_generic_remove_busy(node);
-            if (gam_node_get_subscriptions(node) != NULL) {
-                gam_poll_dnotify_flowoff_node(node);
-            }
-        }
-    }
-    in_poll_callback = 0;
-    return TRUE;
+	return TRUE;
 }
Index: server/gam_poll_generic.c
===================================================================
RCS file: /cvs/gnome/gamin/server/gam_poll_generic.c,v
retrieving revision 1.1
diff -u -r1.1 gam_poll_generic.c
--- server/gam_poll_generic.c	15 Aug 2005 19:34:58 -0000	1.1
+++ server/gam_poll_generic.c	15 Aug 2005 21:52:31 -0000
@@ -43,9 +43,15 @@
 
 static GamTree *	tree = NULL;
 static GList *		missing_resources = NULL;
+static GList *		missing_resources_to_remove = NULL;
+static GList *		missing_resources_to_add = NULL;
 static GList *		busy_resources = NULL;
+static GList *		busy_resources_to_remove = NULL;
+static GList *		busy_resources_to_add = NULL;
 static GList *		all_resources = NULL;
-static GList *		dead_resources = NULL;
+static GList *		all_resources_to_remove = NULL;
+static GList *		all_resources_to_add = NULL;
+static GList *		tree_removal = NULL;
 static time_t		current_time = 0;
 
 gboolean
@@ -99,14 +105,17 @@
 void
 gam_poll_generic_add_missing(GamNode * node)
 {
-	if (g_list_find(missing_resources, node) == NULL) {
-		missing_resources = g_list_prepend(missing_resources, node);
-		GAM_DEBUG(DEBUG_INFO, "Poll: adding missing node %s\n", gam_node_get_path(node));
+	if (g_list_find(missing_resources_to_remove, node)) 
+	{
+		missing_resources_to_remove = g_list_remove_all(missing_resources_to_remove, node);
+	} 
+	if (g_list_find(missing_resources_to_add, node) == NULL) 
+	{
+		missing_resources_to_add = g_list_prepend(missing_resources_to_add, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing add missing node %s\n", gam_node_get_path(node));
 	}
 }
 
-
-
 /**
  * gam_poll_generic_remove_missing:
  * @node: a missing node
@@ -116,9 +125,16 @@
 void
 gam_poll_generic_remove_missing(GamNode * node)
 {
-	g_assert (g_list_find (missing_resources, node));
-	GAM_DEBUG(DEBUG_INFO, "Poll: removing missing node %s\n", gam_node_get_path(node));
-	missing_resources = g_list_remove_all(missing_resources, node);
+	if (g_list_find(missing_resources_to_add, node))
+	{
+		missing_resources_to_add = g_list_remove_all(missing_resources_to_add, node);
+	}
+
+	if (g_list_find(missing_resources_to_remove, node) == NULL)
+	{
+		missing_resources_to_remove = g_list_prepend(missing_resources_to_remove, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing rm of missing node %s\n", gam_node_get_path(node));
+	}
 }
 
 /**
@@ -130,9 +146,14 @@
 void
 gam_poll_generic_add_busy(GamNode * node)
 {
-	if (g_list_find(busy_resources, node) == NULL) {
-		busy_resources = g_list_prepend(busy_resources, node);
-		GAM_DEBUG(DEBUG_INFO, "Poll: adding busy node %s\n", gam_node_get_path(node));
+	if (g_list_find(busy_resources_to_remove, node)) 
+	{
+		busy_resources_to_remove = g_list_remove_all(busy_resources_to_remove, node);
+	} 
+	if (g_list_find(busy_resources_to_add, node) == NULL) 
+	{
+		busy_resources_to_add = g_list_prepend(busy_resources_to_add, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing add busy node %s\n", gam_node_get_path(node));
 	}
 }
 
@@ -145,29 +166,132 @@
 void
 gam_poll_generic_remove_busy(GamNode * node)
 {
-	if (!g_list_find (busy_resources, node))
-		return;
+	if (g_list_find(busy_resources_to_add, node))
+	{
+		busy_resources_to_add = g_list_remove_all(busy_resources_to_add, node);
+	}
 
-	GAM_DEBUG(DEBUG_INFO, "Poll: removing busy node %s\n", gam_node_get_path(node));
-	busy_resources = g_list_remove_all(busy_resources, node);
+	if (g_list_find(busy_resources_to_remove, node) == NULL)
+	{
+		busy_resources_to_remove = g_list_prepend(busy_resources_to_remove, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing rm of busy node %s\n", gam_node_get_path(node));
+	}
 }
 
 void
 gam_poll_generic_add (GamNode * node)
 {
-	if (g_list_find (all_resources, node) == NULL)
+	if (g_list_find(all_resources_to_remove, node))
+	{
+		all_resources_to_remove = g_list_remove_all(all_resources_to_remove, node);
+	}
+
+	if (g_list_find(all_resources_to_add, node) == NULL)
 	{
-		all_resources = g_list_prepend(all_resources, node);
-		GAM_DEBUG(DEBUG_INFO, "Poll: Adding node %s\n", gam_node_get_path (node));
+		all_resources_to_add = g_list_prepend(all_resources_to_add, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing add of node %s\n", gam_node_get_path(node));
 	}
 }
 
 void
 gam_poll_generic_remove (GamNode * node)
 {
-	g_assert (g_list_find (all_resources, node));
-	GAM_DEBUG(DEBUG_INFO, "Poll: removing node %s\n", gam_node_get_path(node));
-	all_resources = g_list_remove_all(all_resources, node);
+	if (g_list_find(all_resources_to_add, node))
+	{
+		all_resources_to_add = g_list_remove_all(all_resources_to_add, node);
+	}
+
+	if (g_list_find(all_resources_to_remove, node) == NULL)
+	{
+		all_resources_to_remove = g_list_prepend(all_resources_to_remove, node);
+		GAM_DEBUG(DEBUG_INFO, "Poll: queueing add of node %s\n", gam_node_get_path(node));
+	}
+}
+
+void
+gam_poll_generic_remove_from_tree (GamNode * node)
+{
+	if (g_list_find(tree_removal, node) == NULL)
+	{
+		tree_removal = g_list_prepend (tree_removal, node);
+	}
+}
+
+void
+gam_poll_generic_flush_node_queues ()
+{
+	GList *l = NULL;
+
+	/* Remove all the nodes scheduled to be removed */
+	l = missing_resources_to_remove;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		missing_resources = g_list_remove_all (missing_resources, node);
+		l = l->next;
+	}
+	g_list_free (missing_resources_to_remove);
+	missing_resources_to_remove = NULL;
+
+	l = busy_resources_to_remove;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		busy_resources = g_list_remove_all (busy_resources, node);
+		l = l->next;
+	}
+	g_list_free (busy_resources_to_remove);
+	busy_resources_to_remove = NULL;
+
+	l = all_resources_to_remove;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		all_resources = g_list_remove_all (all_resources, node);
+		l = l->next;
+	}
+	g_list_free (all_resources_to_remove);
+	all_resources_to_remove = NULL;
+
+	/* Add all the nodes scheduled to be added */
+	l = missing_resources_to_add;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		missing_resources = g_list_prepend (missing_resources, node);
+		l = l->next;
+	}
+	g_list_free (missing_resources_to_add);
+	missing_resources_to_add = NULL;
+
+	l = busy_resources_to_add;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		busy_resources = g_list_prepend (busy_resources, node);
+		l = l->next;
+	}
+	g_list_free (busy_resources_to_add);
+	busy_resources_to_add = NULL;
+
+	l = all_resources_to_add;
+	while (l) 
+	{
+		GamNode *node = l->data;
+		all_resources = g_list_prepend (all_resources, node);
+		l = l->next;
+	}
+	g_list_free (all_resources_to_add);
+	all_resources_to_add = NULL;
+
+	l = tree_removal;
+	while (l)
+	{
+		GamNode *node = l->data;
+		gam_tree_remove (tree, node);
+	}
+	g_list_free (tree_removal);
+	tree_removal = NULL;
 }
 
 time_t
@@ -514,26 +638,17 @@
 	return all_resources;
 }
 
-GList *
-gam_poll_generic_get_dead_list (void)
-{
-	return dead_resources;
-}
-
 void
 gam_poll_generic_unregister_node (GamNode * node)
 {
-	if (missing_resources != NULL) {
+	if (missing_resources != NULL)
 		gam_poll_generic_remove_missing(node);
-	}
 
-	if (busy_resources != NULL) {
+	if (busy_resources != NULL)
 		gam_poll_generic_remove_busy(node);
-	}
 
-	if (all_resources != NULL) {
-		all_resources = g_list_remove(all_resources, node);
-	}
+	if (all_resources != NULL)
+		gam_poll_generic_remove (node);
 }
 
 void
Index: server/gam_poll_generic.h
===================================================================
RCS file: /cvs/gnome/gamin/server/gam_poll_generic.h,v
retrieving revision 1.1
diff -u -r1.1 gam_poll_generic.h
--- server/gam_poll_generic.h	15 Aug 2005 19:34:58 -0000	1.1
+++ server/gam_poll_generic.h	15 Aug 2005 21:52:31 -0000
@@ -16,6 +16,8 @@
 void		gam_poll_generic_remove_busy	(GamNode * node);
 void		gam_poll_generic_add		(GamNode * node);
 void		gam_poll_generic_remove		(GamNode * node);
+void		gam_poll_generic_remove_from_tree (GamNode * node);
+void		gam_poll_generic_flush_node_queues (void);
 
 time_t		gam_poll_generic_get_time		(void);
 void		gam_poll_generic_update_time	(void);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]