diff options
-rw-r--r-- | e-util/e-attachment.c | 133 |
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", |