[nautilus] batch-rename-dialog: Fix thread-unsafe code



commit b2f10eb84dd66fab344bb616f89761fc3aeafa6d
Author: Sachin Daluja <30343-sachindaluja users noreply gitlab gnome org>
Date:   Thu Jul 30 22:42:59 2020 -0400

    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

 src/nautilus-batch-rename-dialog.c | 11 ++++++-----
 1 file 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]