summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin Daluja <30343-sachindaluja@users.noreply.gitlab.gnome.org>2020-07-30 22:42:59 -0400
committerSachin Daluja <30343-sachindaluja@users.noreply.gitlab.gnome.org>2021-01-16 16:05:02 -0500
commitb2f10eb84dd66fab344bb616f89761fc3aeafa6d (patch)
treef2e561689d66217059b5cda8411c7687cd131bc9
parent9b733dd9df9d6d9805c56749d05ada15a7560ef4 (diff)
downloadnautilus-b2f10eb84dd66fab344bb616f89761fc3aeafa6d.tar.gz
batch-rename-dialog: Fix thread-unsafe code
When collecting distinct parent directories of selected files we were accessing and possibly modifying the selected files GList from multiple threads without any synchronization causing unpredictable corruption. We were also performing operations in a background thread on NautilusFile and NautilusDirectory which are not thread safe. Identify distict parent dirs only once during dialog initialization and store it in the instance struct because the selection does not change during operation of the dialog. This eliminates thread-unsafe operations when collecting and accessing the list of distinct parent directories. Closes https://gitlab.gnome.org/GNOME/nautilus/-/issues/1552
-rw-r--r--src/nautilus-batch-rename-dialog.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/nautilus-batch-rename-dialog.c b/src/nautilus-batch-rename-dialog.c
index bc456c7d2..dde67158e 100644
--- a/src/nautilus-batch-rename-dialog.c
+++ b/src/nautilus-batch-rename-dialog.c
@@ -89,6 +89,7 @@ struct _NautilusBatchRenameDialog
gint conflicts_number;
GList *duplicates;
+ GList *distinct_parent_directories;
GCancellable *conflict_cancellable;
gboolean checking_conflicts;
@@ -1265,7 +1266,6 @@ file_names_list_has_duplicates_async_thread (GTask *task,
{
NautilusBatchRenameDialog *self;
CheckConflictsData *task_data;
- GList *directories;
GList *l;
self = g_task_get_source_object (task);
@@ -1275,13 +1275,11 @@ file_names_list_has_duplicates_async_thread (GTask *task,
g_mutex_init (&task_data->wait_ready_mutex);
g_cond_init (&task_data->wait_ready_condition);
- directories = batch_rename_files_get_distinct_parents (self->selection);
/* check if this is the last call of the callback */
- for (l = directories; l != NULL; l = l->next)
+ for (l = self->distinct_parent_directories; l != NULL; l = l->next)
{
if (g_task_return_error_if_cancelled (task))
{
- nautilus_directory_list_free (directories);
return;
}
@@ -1307,7 +1305,6 @@ file_names_list_has_duplicates_async_thread (GTask *task,
}
g_task_return_boolean (task, TRUE);
- nautilus_directory_list_free (directories);
}
static void
@@ -2079,6 +2076,7 @@ nautilus_batch_rename_dialog_finalize (GObject *object)
nautilus_file_list_free (dialog->selection);
nautilus_directory_unref (dialog->directory);
+ nautilus_directory_list_free (dialog->distinct_parent_directories);
g_object_unref (dialog->size_group);
@@ -2212,6 +2210,8 @@ nautilus_batch_rename_dialog_new (GList *selection,
gtk_window_set_title (GTK_WINDOW (dialog), dialog_title->str);
+ dialog->distinct_parent_directories = batch_rename_files_get_distinct_parents (selection);
+
add_tag (dialog, metadata_tags_constants[ORIGINAL_FILE_NAME]);
nautilus_batch_rename_dialog_initialize_actions (dialog);
@@ -2267,6 +2267,7 @@ nautilus_batch_rename_dialog_init (NautilusBatchRenameDialog *self)
gtk_label_set_max_width_chars (GTK_LABEL (self->conflict_label), 1);
self->duplicates = NULL;
+ self->distinct_parent_directories = NULL;
self->new_names = NULL;
self->checking_conflicts = FALSE;