[nautilus/gnome-3-22] progress-info: avoid races



commit fdc903f56073e73cca0abe05dd11f672d2ce43f5
Author: Carlos Soriano <csoriano gnome org>
Date:   Wed Nov 23 15:04:39 2016 +0100

    progress-info: avoid races
    
    We were not checking whether the operations was aborted from the user
    side when setting the details,so that could make a race and the info
    thread setting the details to canceled and the operation thread setting
    the details too afterwards before realizing the operations was canceled.
    
    To fix it, always check whether the info progress was canceled or not.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775094

 src/nautilus-progress-info.c |   82 +++++++++++++++++++++++------------------
 1 files changed, 46 insertions(+), 36 deletions(-)
---
diff --git a/src/nautilus-progress-info.c b/src/nautilus-progress-info.c
index 5a4c7d2..d8ac8d2 100644
--- a/src/nautilus-progress-info.c
+++ b/src/nautilus-progress-info.c
@@ -83,6 +83,11 @@ G_LOCK_DEFINE_STATIC (progress_info);
 
 G_DEFINE_TYPE (NautilusProgressInfo, nautilus_progress_info, G_TYPE_OBJECT)
 
+static void set_details (NautilusProgressInfo *info,
+                         const char           *details);
+static void set_status  (NautilusProgressInfo *info,
+                         const char           *status);
+
 static void
 nautilus_progress_info_finalize (GObject *object)
 {
@@ -309,7 +314,7 @@ set_details_in_thread (GTask                *task,
 {
     if (!g_cancellable_is_cancelled (cancellable))
     {
-        nautilus_progress_info_set_details (info, _("Canceled"));
+        set_details (info, _("Canceled"));
         G_LOCK (progress_info);
         info->cancel_at_idle = TRUE;
         g_timer_stop (info->progress_timer);
@@ -566,26 +571,32 @@ nautilus_progress_info_finish (NautilusProgressInfo *info)
     G_UNLOCK (progress_info);
 }
 
+static void
+set_status (NautilusProgressInfo *info,
+            const char           *status)
+{
+    g_free (info->status);
+    info->status = g_strdup (status);
+
+    info->changed_at_idle = TRUE;
+    queue_idle (info, FALSE);
+}
+
 void
 nautilus_progress_info_take_status (NautilusProgressInfo *info,
                                     char                 *status)
 {
     G_LOCK (progress_info);
 
-    if (g_strcmp0 (info->status, status) != 0)
+    if (g_strcmp0 (info->status, status) != 0 &&
+        !g_cancellable_is_cancelled (info->cancellable))
     {
-        g_free (info->status);
-        info->status = status;
-
-        info->changed_at_idle = TRUE;
-        queue_idle (info, FALSE);
-    }
-    else
-    {
-        g_free (status);
+        set_status (info, status);
     }
 
     G_UNLOCK (progress_info);
+
+    g_free (status);
 }
 
 void
@@ -594,18 +605,25 @@ nautilus_progress_info_set_status (NautilusProgressInfo *info,
 {
     G_LOCK (progress_info);
 
-    if (g_strcmp0 (info->status, status) != 0)
+    if (g_strcmp0 (info->status, status) != 0 &&
+        !g_cancellable_is_cancelled (info->cancellable))
     {
-        g_free (info->status);
-        info->status = g_strdup (status);
-
-        info->changed_at_idle = TRUE;
-        queue_idle (info, FALSE);
+        set_status (info, status);
     }
 
     G_UNLOCK (progress_info);
 }
 
+static void
+set_details (NautilusProgressInfo *info,
+             const char           *details)
+{
+    g_free (info->details);
+    info->details = g_strdup (details);
+
+    info->changed_at_idle = TRUE;
+    queue_idle (info, FALSE);
+}
 
 void
 nautilus_progress_info_take_details (NautilusProgressInfo *info,
@@ -613,20 +631,15 @@ nautilus_progress_info_take_details (NautilusProgressInfo *info,
 {
     G_LOCK (progress_info);
 
-    if (g_strcmp0 (info->details, details) != 0)
+    if (g_strcmp0 (info->details, details) != 0 &&
+        !g_cancellable_is_cancelled (info->cancellable))
     {
-        g_free (info->details);
-        info->details = details;
-
-        info->changed_at_idle = TRUE;
-        queue_idle (info, FALSE);
-    }
-    else
-    {
-        g_free (details);
+        set_details (info, details);
     }
 
     G_UNLOCK (progress_info);
+
+    g_free (details);
 }
 
 void
@@ -635,13 +648,10 @@ nautilus_progress_info_set_details (NautilusProgressInfo *info,
 {
     G_LOCK (progress_info);
 
-    if (g_strcmp0 (info->details, details) != 0)
+    if (g_strcmp0 (info->details, details) != 0 &&
+        !g_cancellable_is_cancelled (info->cancellable))
     {
-        g_free (info->details);
-        info->details = g_strdup (details);
-
-        info->changed_at_idle = TRUE;
-        queue_idle (info, FALSE);
+        set_details (info, details);
     }
 
     G_UNLOCK (progress_info);
@@ -688,9 +698,9 @@ nautilus_progress_info_set_progress (NautilusProgressInfo *info,
 
     G_LOCK (progress_info);
 
-    if (info->activity_mode ||     /* emit on switch from activity mode */
-        fabs (current_percent - info->progress) > 0.005     /* Emit on change of 0.5 percent */
-        )
+    if ((info->activity_mode ||     /* emit on switch from activity mode */
+        fabs (current_percent - info->progress) > 0.005) &&     /* Emit on change of 0.5 percent */
+        !g_cancellable_is_cancelled (info->cancellable))
     {
         info->activity_mode = FALSE;
         info->progress = current_percent;


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