[gnome-builder] progress: make IdeProgress thread-safe
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] progress: make IdeProgress thread-safe
- Date: Thu, 16 Feb 2017 05:08:01 +0000 (UTC)
commit b0cc8852979e7722364bc62d421bcea5d4dbaa81
Author: Christian Hergert <chergert redhat com>
Date: Wed Feb 15 14:44:23 2017 -0800
progress: make IdeProgress thread-safe
This is useful so that we can use an IdeProgress from a thread (such as
a GTask worker) and have UI updates happen in the Gtk thread. This means
we need to change the ownership of ide_progress_get_message() to always
return a copy.
Additionally, we proxy our property notifications to the main thread.
libide/util/ide-progress.c | 52 ++++++++++++++++++++++++++++++++------
libide/util/ide-progress.h | 24 ++++++++++-------
libidemm/src/libide_methods.defs | 2 +-
3 files changed, 59 insertions(+), 19 deletions(-)
---
diff --git a/libide/util/ide-progress.c b/libide/util/ide-progress.c
index a80e547..d546359 100644
--- a/libide/util/ide-progress.c
+++ b/libide/util/ide-progress.c
@@ -20,12 +20,14 @@
#include <glib/gi18n.h>
+#include "ide-object.h"
#include "ide-progress.h"
struct _IdeProgress
{
GObject parent_instance;
+ GMutex mutex;
gchar *message;
gdouble fraction;
guint completed : 1;
@@ -57,19 +59,27 @@ ide_progress_set_completed (IdeProgress *self,
{
g_return_if_fail (IDE_IS_PROGRESS (self));
+ g_mutex_lock (&self->mutex);
if (self->completed != completed)
{
self->completed = completed;
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_COMPLETED]);
+ ide_object_notify_in_main (G_OBJECT (self), properties [PROP_COMPLETED]);
}
+ g_mutex_unlock (&self->mutex);
}
gdouble
ide_progress_get_fraction (IdeProgress *self)
{
+ gdouble ret;
+
g_return_val_if_fail (IDE_IS_PROGRESS (self), 0.0);
- return self->fraction;
+ g_mutex_lock (&self->mutex);
+ ret = self->fraction;
+ g_mutex_unlock (&self->mutex);
+
+ return ret;
}
void
@@ -80,21 +90,29 @@ ide_progress_set_fraction (IdeProgress *self,
g_return_if_fail (fraction >= 0.0);
g_return_if_fail (fraction <= 1.0);
+ g_mutex_lock (&self->mutex);
if (self->fraction != fraction)
{
self->fraction = fraction;
if (fraction == 1.0)
ide_progress_set_completed (self, TRUE);
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FRACTION]);
+ ide_object_notify_in_main (G_OBJECT (self), properties [PROP_FRACTION]);
}
+ g_mutex_unlock (&self->mutex);
}
-const gchar *
+gchar *
ide_progress_get_message (IdeProgress *self)
{
+ gchar *ret;
+
g_return_val_if_fail (IDE_IS_PROGRESS (self), NULL);
- return self->message;
+ g_mutex_lock (&self->mutex);
+ ret = g_strdup (self->message);
+ g_mutex_unlock (&self->mutex);
+
+ return ret;
}
void
@@ -103,12 +121,28 @@ ide_progress_set_message (IdeProgress *self,
{
g_return_if_fail (IDE_IS_PROGRESS (self));
- if (self->message != message)
+ g_mutex_lock (&self->mutex);
+ if (g_strcmp0 (self->message, message) != 0)
{
g_free (self->message);
self->message = g_strdup (message);
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MESSAGE]);
+ ide_object_notify_in_main (G_OBJECT (self), properties [PROP_MESSAGE]);
}
+ g_mutex_unlock (&self->mutex);
+}
+
+void
+ide_progress_flatpak_progress_callback (const char *status,
+ guint progress,
+ gboolean estimating,
+ gpointer user_data)
+{
+ IdeProgress *self = user_data;
+
+ g_return_if_fail (IDE_IS_PROGRESS (self));
+
+ ide_progress_set_message (self, status);
+ ide_progress_set_fraction (self, (gdouble)progress / 100.0);
}
/**
@@ -142,6 +176,7 @@ ide_progress_finalize (GObject *object)
IdeProgress *self = (IdeProgress *)object;
g_clear_pointer (&self->message, g_free);
+ g_mutex_clear (&self->mutex);
G_OBJECT_CLASS (ide_progress_parent_class)->finalize (object);
}
@@ -165,7 +200,7 @@ ide_progress_get_property (GObject *object,
break;
case PROP_MESSAGE:
- g_value_set_string (value, ide_progress_get_message (self));
+ g_value_take_string (value, ide_progress_get_message (self));
break;
default:
@@ -234,6 +269,7 @@ ide_progress_class_init (IdeProgressClass *klass)
static void
ide_progress_init (IdeProgress *self)
{
+ g_mutex_init (&self->mutex);
}
IdeProgress *
diff --git a/libide/util/ide-progress.h b/libide/util/ide-progress.h
index 1064b73..e4cbb91 100644
--- a/libide/util/ide-progress.h
+++ b/libide/util/ide-progress.h
@@ -27,16 +27,20 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeProgress, ide_progress, IDE, PROGRESS, GObject)
-IdeProgress *ide_progress_new (void);
-gdouble ide_progress_get_fraction (IdeProgress *self);
-const gchar *ide_progress_get_message (IdeProgress *self);
-void ide_progress_set_fraction (IdeProgress *self,
- gdouble fraction);
-void ide_progress_set_message (IdeProgress *self,
- const gchar *message);
-void ide_progress_file_progress_callback (goffset current_num_bytes,
- goffset total_num_bytes,
- gpointer user_data);
+IdeProgress *ide_progress_new (void);
+gdouble ide_progress_get_fraction (IdeProgress *self);
+gchar *ide_progress_get_message (IdeProgress *self);
+void ide_progress_set_fraction (IdeProgress *self,
+ gdouble fraction);
+void ide_progress_set_message (IdeProgress *self,
+ const gchar *message);
+void ide_progress_flatpak_progress_callback (const char *status,
+ guint progress,
+ gboolean estimating,
+ gpointer user_data);
+void ide_progress_file_progress_callback (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data);
G_END_DECLS
diff --git a/libidemm/src/libide_methods.defs b/libidemm/src/libide_methods.defs
index 7aacbc6..d4949e6 100644
--- a/libidemm/src/libide_methods.defs
+++ b/libidemm/src/libide_methods.defs
@@ -3618,7 +3618,7 @@
(define-method get_message
(of-object "IdeProgress")
(c-name "ide_progress_get_message")
- (return-type "const-gchar*")
+ (return-type "gchar*")
)
(define-method set_fraction
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]