summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2016-11-23 15:04:39 +0100
committerCarlos Soriano <csoriano@gnome.org>2016-11-25 17:13:36 +0100
commit27783cc8c234e533fb4ec4401efe3b41238220c7 (patch)
tree104219081c7b3cd87273e0a496ebeb0cd120ba4c
parent12476f47ecf012a80734e5d9aa4f7f17ab81b3bd (diff)
downloadnautilus-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
-rw-r--r--src/nautilus-progress-info.c82
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;