aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--e-util/e-attachment.c133
1 files changed, 125 insertions, 8 deletions
diff --git a/e-util/e-attachment.c b/e-util/e-attachment.c
index 10f251379e..e068b13a90 100644
--- a/e-util/e-attachment.c
+++ b/e-util/e-attachment.c
@@ -82,6 +82,13 @@ struct _EAttachmentPrivate {
* If we are removed from the store, we lazily free the
* reference when it is found to be to be invalid. */
GtkTreeRowReference *reference;
+
+ /* These are IDs for idle callbacks,
+ * protected by the idle_lock mutex. */
+ GMutex idle_lock;
+ guint update_icon_column_idle_id;
+ guint update_progress_columns_idle_id;
+ guint update_file_info_columns_idle_id;
};
enum {
@@ -195,9 +202,10 @@ attachment_get_default_charset (void)
return charset;
}
-static void
-attachment_update_file_info_columns (EAttachment *attachment)
+static gboolean
+attachment_update_file_info_columns_idle_cb (gpointer weak_ref)
{
+ EAttachment *attachment;
GtkTreeRowReference *reference;
GtkTreeModel *model;
GtkTreePath *path;
@@ -211,13 +219,21 @@ attachment_update_file_info_columns (EAttachment *attachment)
gchar *caption;
goffset size;
+ attachment = g_weak_ref_get (weak_ref);
+ if (attachment == NULL)
+ goto exit;
+
+ g_mutex_lock (&attachment->priv->idle_lock);
+ attachment->priv->update_file_info_columns_idle_id = 0;
+ g_mutex_unlock (&attachment->priv->idle_lock);
+
reference = e_attachment_get_reference (attachment);
if (!gtk_tree_row_reference_valid (reference))
- return;
+ goto exit;
file_info = e_attachment_ref_file_info (attachment);
if (file_info == NULL)
- return;
+ goto exit;
model = gtk_tree_row_reference_get_model (reference);
path = gtk_tree_row_reference_get_path (reference);
@@ -257,11 +273,36 @@ attachment_update_file_info_columns (EAttachment *attachment)
g_free (caption);
g_clear_object (&file_info);
+
+exit:
+ g_clear_object (&attachment);
+
+ return FALSE;
}
static void
-attachment_update_icon_column (EAttachment *attachment)
+attachment_update_file_info_columns (EAttachment *attachment)
+{
+ g_mutex_lock (&attachment->priv->idle_lock);
+
+ if (attachment->priv->update_file_info_columns_idle_id == 0) {
+ guint idle_id;
+
+ idle_id = g_idle_add_full (
+ G_PRIORITY_HIGH_IDLE,
+ attachment_update_file_info_columns_idle_cb,
+ e_weak_ref_new (attachment),
+ (GDestroyNotify) e_weak_ref_free);
+ attachment->priv->update_file_info_columns_idle_id = idle_id;
+ }
+
+ g_mutex_unlock (&attachment->priv->idle_lock);
+}
+
+static gboolean
+attachment_update_icon_column_idle_cb (gpointer weak_ref)
{
+ EAttachment *attachment;
GtkTreeRowReference *reference;
GtkTreeModel *model;
GtkTreePath *path;
@@ -272,9 +313,17 @@ attachment_update_icon_column (EAttachment *attachment)
const gchar *emblem_name = NULL;
const gchar *thumbnail_path = NULL;
+ attachment = g_weak_ref_get (weak_ref);
+ if (attachment == NULL)
+ goto exit;
+
+ g_mutex_lock (&attachment->priv->idle_lock);
+ attachment->priv->update_icon_column_idle_id = 0;
+ g_mutex_unlock (&attachment->priv->idle_lock);
+
reference = e_attachment_get_reference (attachment);
if (!gtk_tree_row_reference_valid (reference))
- return;
+ goto exit;
model = gtk_tree_row_reference_get_model (reference);
path = gtk_tree_row_reference_get_path (reference);
@@ -387,11 +436,36 @@ attachment_update_icon_column (EAttachment *attachment)
g_object_notify (G_OBJECT (attachment), "icon");
g_clear_object (&file_info);
+
+exit:
+ g_clear_object (&attachment);
+
+ return FALSE;
}
static void
-attachment_update_progress_columns (EAttachment *attachment)
+attachment_update_icon_column (EAttachment *attachment)
{
+ g_mutex_lock (&attachment->priv->idle_lock);
+
+ if (attachment->priv->update_icon_column_idle_id == 0) {
+ guint idle_id;
+
+ idle_id = g_idle_add_full (
+ G_PRIORITY_HIGH_IDLE,
+ attachment_update_icon_column_idle_cb,
+ e_weak_ref_new (attachment),
+ (GDestroyNotify) e_weak_ref_free);
+ attachment->priv->update_icon_column_idle_id = idle_id;
+ }
+
+ g_mutex_unlock (&attachment->priv->idle_lock);
+}
+
+static gboolean
+attachment_update_progress_columns_idle_cb (gpointer weak_ref)
+{
+ EAttachment *attachment;
GtkTreeRowReference *reference;
GtkTreeModel *model;
GtkTreePath *path;
@@ -400,9 +474,17 @@ attachment_update_progress_columns (EAttachment *attachment)
gboolean saving;
gint percent;
+ attachment = g_weak_ref_get (weak_ref);
+ if (attachment == NULL)
+ goto exit;
+
+ g_mutex_lock (&attachment->priv->idle_lock);
+ attachment->priv->update_progress_columns_idle_id = 0;
+ g_mutex_unlock (&attachment->priv->idle_lock);
+
reference = e_attachment_get_reference (attachment);
if (!gtk_tree_row_reference_valid (reference))
- return;
+ goto exit;
model = gtk_tree_row_reference_get_model (reference);
path = gtk_tree_row_reference_get_path (reference);
@@ -420,6 +502,30 @@ attachment_update_progress_columns (EAttachment *attachment)
E_ATTACHMENT_STORE_COLUMN_PERCENT, percent,
E_ATTACHMENT_STORE_COLUMN_SAVING, saving,
-1);
+
+exit:
+ g_clear_object (&attachment);
+
+ return FALSE;
+}
+
+static void
+attachment_update_progress_columns (EAttachment *attachment)
+{
+ g_mutex_lock (&attachment->priv->idle_lock);
+
+ if (attachment->priv->update_progress_columns_idle_id == 0) {
+ guint idle_id;
+
+ idle_id = g_idle_add_full (
+ G_PRIORITY_HIGH_IDLE,
+ attachment_update_progress_columns_idle_cb,
+ e_weak_ref_new (attachment),
+ (GDestroyNotify) e_weak_ref_free);
+ attachment->priv->update_progress_columns_idle_id = idle_id;
+ }
+
+ g_mutex_unlock (&attachment->priv->idle_lock);
}
static void
@@ -706,7 +812,17 @@ attachment_finalize (GObject *object)
priv = E_ATTACHMENT_GET_PRIVATE (object);
+ if (priv->update_icon_column_idle_id > 0)
+ g_source_remove (priv->update_icon_column_idle_id);
+
+ if (priv->update_progress_columns_idle_id > 0)
+ g_source_remove (priv->update_progress_columns_idle_id);
+
+ if (priv->update_file_info_columns_idle_id > 0)
+ g_source_remove (priv->update_file_info_columns_idle_id);
+
g_mutex_clear (&priv->property_lock);
+ g_mutex_clear (&priv->idle_lock);
g_free (priv->disposition);
@@ -881,6 +997,7 @@ e_attachment_init (EAttachment *attachment)
attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE;
g_mutex_init (&attachment->priv->property_lock);
+ g_mutex_init (&attachment->priv->idle_lock);
g_signal_connect (
attachment, "notify::encrypted",