Re: [gamin] Patch : fix poll only mode in gamin



Le mercredi 22 décembre 2004 à 20:05 +0100, Frederic Crozat a écrit :
> Hi,
> 
> the attached patch is fixing (ie implementing) poll only mode in gamin.
> I'm not sure patch is 100% stable, I'm still having crashes when
> removing a lot of monitors, but since I'll be offline for Christmas, I
> prefer to send this "work in progress". Good news is you can use
> valgrind with poll only mode :)

Ok, I've just fixed this crash and for me, poll only mode is now stable.

I've attached the new patch.

-- 
Frederic Crozat <fcrozat mandrakesoft com>
Mandrakesoft
? .gam_poll.c.swp
? Makefile
? Makefile.in
? gam-pollonly.patch
? gam-pollonly1.patch
? gam_server
Index: gam_poll.c
===================================================================
RCS file: /cvs/gnome/gamin/server/gam_poll.c,v
retrieving revision 1.27
diff -u -p -r1.27 gam_poll.c
--- gam_poll.c	3 Dec 2004 15:12:54 -0000	1.27
+++ gam_poll.c	5 Jan 2005 10:37:07 -0000
@@ -60,6 +60,7 @@ static GamTree *tree = NULL;
 static GList *new_subs = NULL;
 static GList *removed_subs = NULL;
 static GList *missing_resources = NULL;
+static GList *all_resources = NULL;
 static GamPollHandler dir_handler = NULL;
 static GamPollHandler file_handler = NULL;
 
@@ -662,11 +663,141 @@ prune_tree(GamNode * node)
         GamNode *parent;
 
         parent = gam_node_parent(node);
+	if (missing_resources != NULL) {
+                gam_poll_remove_missing (node);
+        }
+	if (all_resources != NULL) {
+                all_resources = g_list_remove (all_resources, node);
+        }
         gam_tree_remove(tree, node);
         prune_tree(parent);
     }
 }
 
+static gboolean
+gam_poll_scan_all_callback(gpointer data) {
+    int idx;
+    GList *subs, *l;
+    GamNode *node;
+
+    static int in_poll_callback = 0;
+
+    if (in_poll_callback)
+	return(TRUE);
+ 
+    in_poll_callback++;
+
+    if (new_subs != NULL) {
+        /* we don't want to block the main loop */
+        subs = new_subs;
+        new_subs = NULL;
+
+        GAM_DEBUG(DEBUG_INFO,
+                  "%d new subscriptions.\n", g_list_length(subs));
+
+        for (l = subs; l; l = l->next) {
+            GamSubscription *sub = l->data;
+
+            const char *path = gam_subscription_get_path(sub);
+
+            node = gam_tree_get_at_path(tree, path);
+            if (!node) {
+                node = gam_tree_add_at_path(tree, path,
+                                            gam_subscription_is_dir(sub));
+            }
+
+            if (node_add_subscription(node, sub) < 0) {
+                gam_error(DEBUG_INFO,
+                          "Failed to add subscription for: %s\n", path);
+	    }
+    	    if (!gam_node_is_dir(node)) {
+		    char *parent;
+		    
+		    parent = g_path_get_dirname (path);
+		    node = gam_tree_get_at_path(tree, parent);
+	            if (!node) {
+	                node = gam_tree_add_at_path(tree, parent,
+                                            gam_subscription_is_dir(sub));
+        	    }
+		    g_free (parent);
+	    }
+
+	      if (g_list_find(all_resources, node) == NULL) {
+		all_resources = g_list_prepend (all_resources, node);
+	      }
+    	}
+	g_list_free (subs);
+    }
+
+    if (removed_subs) {
+        subs = removed_subs;
+        removed_subs = NULL;
+
+        for (l = subs; l; l = l->next) {
+            GamSubscription *sub = l->data;
+            GamNode *node = gam_tree_get_at_path(tree,
+                                                 gam_subscription_get_path
+                                                 (sub));
+
+            GAM_DEBUG(DEBUG_INFO, "Removing: %s\n",
+                      gam_subscription_get_path(sub));
+            if (node != NULL) {
+                if (!gam_node_is_dir(node)) {
+                    node_remove_subscription(node, sub);
+
+                    if (!gam_node_get_subscriptions(node)) {
+                        GamNode *parent;
+
+                        if (all_resources != NULL) {
+                            all_resources = g_list_remove (all_resources, node);
+                        }
+                        if (gam_tree_has_children(tree, node)) {
+                            fprintf(stderr,
+                                    "node %s is not dir but has children\n",
+                                    gam_node_get_path(node));
+                        } else {
+                            parent = gam_node_parent(node);
+                            gam_tree_remove(tree, node);
+
+                            prune_tree(parent);
+                        }
+                    }
+                } else {
+                    if (remove_directory_subscription(node, sub)) {
+                        GamNode *parent;
+
+                        if (all_resources != NULL) {
+                            all_resources = g_list_remove (all_resources, node);
+                        }
+                        parent = gam_node_parent(node);
+                        gam_tree_remove(tree, node);
+
+                        prune_tree(parent);
+                    }
+                }
+	    }
+	}
+
+    }
+
+    current_time = time(NULL);
+    for (idx = 0;;idx++) {
+	
+	/*
+	 * do not simply walk the list as it may be modified in the callback
+	 */
+	node = (GamNode *) g_list_nth_data(all_resources, idx);
+
+	if (node == NULL) {
+	    break;
+	} 
+
+	gam_poll_scan_directory_internal(node, NULL, TRUE);
+    }
+
+    in_poll_callback = 0;
+    return(TRUE);
+}
 
 
 /**
@@ -734,6 +865,7 @@ gam_poll_init_full(gboolean start_scan_t
         g_timeout_add(1000, gam_poll_scan_callback, NULL);
 	poll_mode = 1;
     } else {
+        g_timeout_add(1000, gam_poll_scan_all_callback, NULL);
 	poll_mode = 2;
     }
     tree = gam_tree_new();


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