Merge lp:~gue5t/midori/addons-iter-invalidation into lp:midori

Proposed by gue5t gue5t
Status: Merged
Approved by: Paweł Forysiuk
Approved revision: 6703
Merged at revision: 6885
Proposed branch: lp:~gue5t/midori/addons-iter-invalidation
Merge into: lp:midori
Diff against target: 66 lines (+22/-2)
1 file modified
extensions/addons.c (+22/-2)
To merge this branch: bzr merge lp:~gue5t/midori/addons-iter-invalidation
Reviewer Review Type Date Requested Status
Paweł Forysiuk Approve
Cris Dywan needs-testing Approve
Review via email: mp+220343@code.launchpad.net

Commit message

Avoid bugs due to race condition in addons delete dialog

Description of the change

From the bug report comments:
It looks like addons is sloppy in keeping track of references to rows in its treeview, which is repopulated when it notices the filesystem changes (it notices this at most once per second). Thus, if you delete a script and then delete another without waiting a couple seconds in between, the second "delete?" dialog is interrupted by the filesystem change being noticed and loses its reference to the selected row.

This change uses a GtkTreeRowReference to catch changes to the GtkTreeView and avoids keeping the pointer to the element across a call to gtk_dialog_run, which invokes the main loop and may result in the element list being reconstructed and old elements being freed.

To post a comment you must log in.
6703. By gue5t <email address hidden>

Fix leak

Revision history for this message
Cris Dywan (kalikiana) wrote :

I like the approach. Presumably unit testing it isn't easy… has anyone else manually tested it? Volunteers step up!

review: Approve (needs-testing)
Revision history for this message
Paweł Forysiuk (tuxator) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'extensions/addons.c'
2--- extensions/addons.c 2014-02-22 22:35:42 +0000
3+++ extensions/addons.c 2014-05-21 03:33:43 +0000
4@@ -393,6 +393,9 @@
5 {
6 GtkTreeModel* model;
7 GtkTreeIter iter;
8+ GtkTreePath* path;
9+ GtkTreeRowReference* row;
10+ gchar* fullpath;
11
12 if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (addons->treeview),
13 &model, &iter))
14@@ -403,6 +406,11 @@
15 gchar* markup;
16
17 gtk_tree_model_get (model, &iter, 0, &element, -1);
18+ fullpath = g_strdup (element->fullpath);
19+
20+ path = gtk_tree_model_get_path (model, &iter);
21+ row = gtk_tree_row_reference_new (model, path);
22+ gtk_tree_path_free (path);
23 dialog = gtk_message_dialog_new (
24 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
25 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
26@@ -424,6 +432,9 @@
27 GTK_MESSAGE_DIALOG (dialog), "%s", markup);
28 g_free (markup);
29
30+ /* The execution of gtk_dialog_run allows the directory watcher to
31+ rebuild the treeview and the element list, so our references may be
32+ invalid afterward */
33 delete_response = gtk_dialog_run (GTK_DIALOG (dialog));
34 gtk_widget_destroy (GTK_WIDGET (dialog));
35
36@@ -433,7 +444,7 @@
37 GFile* file;
38 gboolean result;
39
40- file = g_file_new_for_path (element->fullpath);
41+ file = g_file_new_for_path (fullpath);
42 result = g_file_delete (file, NULL, &error);
43
44 if (!result && error)
45@@ -452,11 +463,20 @@
46 g_error_free (error);
47 }
48
49- if (result)
50+ /* The row reference may have been invalidated if the
51+ filesystem watcher deleted the row concurrently */
52+ if (result && gtk_tree_row_reference_valid (row))
53+ {
54+ path = gtk_tree_row_reference_get_path (row);
55+ gtk_tree_model_get_iter (model, &iter, path);
56+ gtk_tree_path_free (path);
57 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
58+ }
59
60+ gtk_tree_row_reference_free (row);
61 g_object_unref (file);
62 }
63+ g_free (fullpath);
64 }
65 }
66 static void

Subscribers

People subscribed via source and target branches

to all changes: