diff options
author | Carlos Soriano <csoriano@gnome.org> | 2016-11-23 15:04:39 +0100 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2016-11-25 17:13:36 +0100 |
commit | 27783cc8c234e533fb4ec4401efe3b41238220c7 (patch) | |
tree | 104219081c7b3cd87273e0a496ebeb0cd120ba4c /src | |
parent | 12476f47ecf012a80734e5d9aa4f7f17ab81b3bd (diff) | |
download | nautilus-27783cc8c234e533fb4ec4401efe3b41238220c7.tar.gz |
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
Diffstat (limited to 'src')
-rw-r--r-- | 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 5a4c7d208..d8ac8d226 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; |