[gamin] Patch : fix poll only mode in gamin
- From: Frederic Crozat <fcrozat mandrakesoft com>
- To: gamin-list gnome org
- Subject: [gamin] Patch : fix poll only mode in gamin
- Date: Wed, 22 Dec 2004 20:05:49 +0100
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]