directory-async: don't modify priv data on cancelled

What we are doing:
Directory starts io.
It cancels the cancellables associated to each async operation.
It starts new operations.
When the new operation finishes, either because it's cancelled or
because it successfully finished, it modifies the directory private
data and sets its associated cancellable as NULL to indicate the
directory that it's all done, so the directory just checks for the
cancellables in its private data to know if there is some operation
going on.

However, what can happens is:
Directory starts io.
It cancels the cancellables and sets as null to start a new operation.
It starts a new operation.
The old operation finishes cancelled, and sets as null the private
cancellable of the directory.
Now the directory thinks there is no operation going on, but actually
the new operation is still going on.
The directory starts io and checks if there is something to stop, but
sees there is no cancellable and keeps going.
Then the new operation finishes and hits an assert when realizes that
the directory state is inconsistent.

To fix this, don't set as null the cancellable in the private data of
the directory when the operation has been cancelled.

It's okay to set as null when the operation finishes succesfully, since
it's ensured that only one operation can be running withouth being
cancelled.

https://bugzilla.gnome.org/show_bug.cgi?id=759608
This commit is contained in:
Carlos Soriano 2015-12-18 18:00:04 +01:00
parent d81d6bae23
commit ec05b0a28e

View file

@ -2337,7 +2337,6 @@ count_more_files_callback (GObject *source_object,
if (g_cancellable_is_cancelled (state->cancellable)) {
/* Operation was cancelled. Bail out */
directory->details->count_in_progress = NULL;
async_job_end (directory, "directory count");
nautilus_directory_async_state_changed (directory);
@ -2391,7 +2390,6 @@ count_children_callback (GObject *source_object,
if (g_cancellable_is_cancelled (state->cancellable)) {
/* Operation was cancelled. Bail out */
directory = state->directory;
directory->details->count_in_progress = NULL;
async_job_end (directory, "directory count");
nautilus_directory_async_state_changed (directory);