[gamin] Patch : fix poll only mode in gamin



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 :)

Stack trace for crash obtained by removing a lot of monitors is :

==6249== Invalid read of size 4
==6249==    at 0x804AD54: gam_node_get_path (gam_node.c:144)
==6249==    by 0x804BF1B: gam_poll_scan_directory_internal
(gam_poll.c:414)
==6249==    by 0x804C493: gam_poll_scan_all_callback (gam_poll.c:792)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249==    by 0x804ABD9: main (gam_server.c:353)
==6249==  Address 0x1BB09B48 is 0 bytes inside a block of size 28 free'd
==6249==    at 0x1B904349: free (vg_replace_malloc.c:153)
==6249==    by 0x1B92F0C1: IA__g_free (gmem.c:187)
==6249==    by 0x804ACED: gam_node_free (gam_node.c:83)
==6249==    by 0x804B057: gam_tree_remove (gam_tree.c:151)
==6249==    by 0x804B931: prune_tree (gam_poll.c:667)
==6249==    by 0x804C624: gam_poll_scan_all_callback (gam_poll.c:772)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249== 
==6249== Invalid read of size 4
==6249==    at 0x804AD67: gam_node_get_subscriptions (gam_node.c:158)
==6249==    by 0x804C047: gam_poll_scan_directory_internal
(gam_poll.c:421)
==6249==    by 0x804C493: gam_poll_scan_all_callback (gam_poll.c:792)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249==    by 0x804ABD9: main (gam_server.c:353)
==6249==  Address 0x1BB09B4C is 4 bytes inside a block of size 28 free'd
==6249==    at 0x1B904349: free (vg_replace_malloc.c:153)
==6249==    by 0x1B92F0C1: IA__g_free (gmem.c:187)
==6249==    by 0x804ACED: gam_node_free (gam_node.c:83)
==6249==    by 0x804B057: gam_tree_remove (gam_tree.c:151)
==6249==    by 0x804B931: prune_tree (gam_poll.c:667)
==6249==    by 0x804C624: gam_poll_scan_all_callback (gam_poll.c:772)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)


==6249== Invalid read of size 4
==6249==    at 0x804AD2E: gam_node_is_dir (gam_node.c:116)
==6249==    by 0x804BF3D: gam_poll_scan_directory_internal
(gam_poll.c:469)
==6249==    by 0x804C493: gam_poll_scan_all_callback (gam_poll.c:792)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249==    by 0x804ABD9: main (gam_server.c:353)
==6249==  Address 0x1BB09B60 is 24 bytes inside a block of size 28
free'd
==6249==    at 0x1B904349: free (vg_replace_malloc.c:153)
==6249==    by 0x1B92F0C1: IA__g_free (gmem.c:187)
==6249==    by 0x804ACED: gam_node_free (gam_node.c:83)
==6249==    by 0x804B057: gam_tree_remove (gam_tree.c:151)
==6249==    by 0x804B931: prune_tree (gam_poll.c:667)
==6249==    by 0x804C624: gam_poll_scan_all_callback (gam_poll.c:772)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)


==6249== Invalid read of size 4
==6249==    at 0x804B26D: gam_tree_get_children (gam_tree.c:258)
==6249==    by 0x804BF80: gam_poll_scan_directory_internal
(gam_poll.c:479)
==6249==    by 0x804C493: gam_poll_scan_all_callback (gam_poll.c:792)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249==    by 0x804ABD9: main (gam_server.c:353)
==6249==  Address 0x1BB09B5C is 20 bytes inside a block of size 28
free'd
==6249==    at 0x1B904349: free (vg_replace_malloc.c:153)
==6249==    by 0x1B92F0C1: IA__g_free (gmem.c:187)
==6249==    by 0x804ACED: gam_node_free (gam_node.c:83)
==6249==    by 0x804B057: gam_tree_remove (gam_tree.c:151)
==6249==    by 0x804B931: prune_tree (gam_poll.c:667)
==6249==    by 0x804C624: gam_poll_scan_all_callback (gam_poll.c:772)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249== 


==6249== Invalid read of size 4
==6249==    at 0x1B9327BA: IA__g_node_n_children (gnode.c:915)
==6249==    by 0x804B285: gam_tree_get_children (gam_tree.c:261)
==6249==    by 0x804BF80: gam_poll_scan_directory_internal
(gam_poll.c:479)
==6249==    by 0x804C493: gam_poll_scan_all_callback (gam_poll.c:792)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
==6249==    by 0x804ABD9: main (gam_server.c:353)
==6249==  Address 0x1BB09BF0 is 16 bytes inside a block of size 20
free'd
==6249==    at 0x1B904349: free (vg_replace_malloc.c:153)
==6249==    by 0x1B92F0C1: IA__g_free (gmem.c:187)
==6249==    by 0x1B931875: g_nodes_free (gnode.c:198)
==6249==    by 0x804B04F: gam_tree_remove (gam_tree.c:150)
==6249==    by 0x804B931: prune_tree (gam_poll.c:667)
==6249==    by 0x804C624: gam_poll_scan_all_callback (gam_poll.c:772)
==6249==    by 0x1B92B783: g_timeout_dispatch (gmain.c:3306)
==6249==    by 0x1B928E5A: IA__g_main_context_dispatch (gmain.c:1947)
==6249==    by 0x1B92A7D8: g_main_context_iterate (gmain.c:2578)
==6249==    by 0x1B92AA63: IA__g_main_loop_run (gmain.c:2782)
-- 
Frederic Crozat <fcrozat mandrakesoft com>
Mandrakesoft
? .gam_dnotify.c.swp
? .gam_poll.c.swp
? .gam_tree.c.swp
? Makefile
? Makefile.in
? gam-pollonly.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	22 Dec 2004 18:50:43 -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;
 
@@ -668,6 +669,132 @@ prune_tree(GamNode * node)
 }
 
 
+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);
+		    g_print("parent %s\n",parent);
+		    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) && (g_list_find(all_resources, node) == 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) && (g_list_find(all_resources, node) == 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);
+}
+
 
 /**
  * @defgroup Polling Polling Backend
@@ -734,6 +861,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]