After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 687196 - filesystemmodel: invalidate nodes on file remove
filesystemmodel: invalidate nodes on file remove
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkFileChooser
unspecified
Other All
: Normal normal
: ---
Assigned To: Federico Mena Quintero
Federico Mena Quintero
: 666158 679257 680586 680628 689515 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2012-10-30 13:29 UTC by fakey
Modified: 2013-05-22 07:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
filesystemmodel: invalidate nodes on file remove (1.05 KB, patch)
2012-10-30 13:29 UTC, fakey
none Details | Review

Description fakey 2012-10-30 13:29:31 UTC
The file system model isn't properly invalidated when a file is removed from
the model. This causes an assertion (r == n_visible_rows) to fail at some later
point in the future when the model is re-sorted.

The bug can be reproduced by opening a GtkFileChooser to a directory with
non-hidden files, and renaming (using the terminal) a file (not the last) to be
last in the sort order.

This bug is reported with several duplicates happening on Ubuntu as
https://bugs.launchpad.net/ubuntu/+source/gtk+3.0/+bug/851843. It may be
related to https://bugzilla.gnome.org/show_bug.cgi?id=666158.
Comment 1 fakey 2012-10-30 13:29:34 UTC
Created attachment 227637 [details] [review]
filesystemmodel: invalidate nodes on file remove

The file system model isn't properly invalidated when a file is removed
from the model. This causes an assertion (r == n_visible_rows) to fail
at some later point in the future when the model is re-sorted.
Comment 2 Federico Mena Quintero 2012-11-01 02:58:16 UTC
You are completely correct in saying that *right there* the model needs to be invalidated.  However, the invalidation should already happen via the existing call to node_set_visible_and_filtered_out().

But now that I look at this again, there are some problems.  That function can return prematurely if the node is already not visible (e.g. remove_file() on a file that was invisible due to being a hidden or backup file), and in that case, the model wouldn't be invalidated.

Also, treemodel signals should only be emitted when the model itself is in a consistent state.  Right now we emit them in the middle of things.

Finally, I think remove_file() is a bit overzealous when it comes to clearing the files hash table.  It should be enough to update the files that will get their indexes changed.

I'm starting to do these fixes; this will hopefully fix the bug.  I cannot reproduce it reliably yet :(
Comment 3 fakey 2012-11-01 14:41:51 UTC
Thanks very much, Federico. After a bit of further testing, I see why the re-invalidation is required, or some suitable alternative fix.

emit_row_deleted_for_row () emits a row-deleted signal, which indirectly triggers gtk_file_system_model_get_iter (), causing the model to re-validate *before* the file system node is finally removed from the model->files array.

There's may be a better solution than re-invalidating at the end of remove_file (), but it would not be as trivial to fix. Also, it was suggested by others that we should use GSequence as a data structure instead.

Here's a stack trace showing what's happening. Please ignore the line numbers.

  • #0 node_validate_rows
    at gtkfilesystemmodel.c line 240
  • #1 gtk_file_system_model_iter_nth_child
    at gtkfilesystemmodel.c line 557
  • #2 gtk_file_system_model_get_iter
    at gtkfilesystemmodel.c line 577
  • #3 gtk_tree_model_get_iter
    at gtktreemodel.c line 1239
  • #4 gtk_tree_model_filter_convert_iter_to_child_iter
    at gtktreemodelfilter.c line 4038
  • #5 gtk_tree_model_filter_real_ref_node
    at gtktreemodelfilter.c line 3464
  • #6 gtk_tree_model_filter_row_deleted
    at gtktreemodelfilter.c line 2664
  • #7 g_cclosure_marshal_VOID__BOXED
    at gmarshal.c line 1120
  • #8 g_closure_invoke
    at gclosure.c line 777
  • #9 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #10 g_signal_emit_valist
    at gsignal.c line 3300
  • #11 g_signal_emit
    at gsignal.c line 3356
  • #12 gtk_tree_model_row_deleted
    at gtktreemodel.c line 1868
  • #13 emit_row_deleted_for_row
    at gtkfilesystemmodel.c line 320
  • #14 node_set_visible_and_filtered_out
    at gtkfilesystemmodel.c line 362
  • #15 remove_file
    at gtkfilesystemmodel.c line 1858

Comment 4 Federico Mena Quintero 2012-11-01 18:04:48 UTC
Perfect, thanks for figuring this out!  That trace is exactly the evidence we needed.

I'll make sure that signal emissions happen only when the model is in a consistent state.  They have to be emitted outside of node_set_visible...() and at the very end of the add/remove functions.
Comment 5 Federico Mena Quintero 2012-11-02 04:35:27 UTC
These are the changes I'm making (in addition to some drive-by cleanups):

* The filtering/visibility of the deleted node is not updated.  The node will simply be gone; we don't need to update those values at all.

* We invalidate just the node that is being deleted.

* The model->file_lookup hash table is not completely nuked; instead, we carefully adjust its indices.

* The row-deleted signal is only emitted at the very end, when deletion is complete and the model is consistent.
Comment 6 Federico Mena Quintero 2012-11-02 04:36:52 UTC
*** Bug 666158 has been marked as a duplicate of this bug. ***
Comment 7 Federico Mena Quintero 2012-11-02 04:37:16 UTC
*** Bug 653038 has been marked as a duplicate of this bug. ***
Comment 8 Benjamin Berg 2012-11-02 08:46:21 UTC
*** Bug 680586 has been marked as a duplicate of this bug. ***
Comment 9 Federico Mena Quintero 2012-11-02 20:25:26 UTC
I've pushed this to the master and gtk-3-6 branches.  In subsequent commits I'll clean up add_file() and the other code that emits signals in not quite the right place.

Thanks, William, for figuring this out! :)
Comment 10 Milan Crha 2013-01-07 11:41:16 UTC
I just got a similar crash report from 3.4.4 of evolution [1]. Do you think it is caused by the same reason as this bug report is filled against? I think it is, but it'll be better if you could confirm it.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=889612
Comment 11 Timothy Arceri 2013-05-20 04:58:22 UTC
*** Bug 680628 has been marked as a duplicate of this bug. ***
Comment 12 Timothy Arceri 2013-05-21 22:03:53 UTC
*** Bug 679257 has been marked as a duplicate of this bug. ***
Comment 13 Timothy Arceri 2013-05-22 07:20:28 UTC
*** Bug 689515 has been marked as a duplicate of this bug. ***