[evolution] Make EAttachment a little more thread-safe.



commit 9058c6f85dc49f9500e7e67819acfd8c0d2d369c
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed May 22 12:11:59 2013 -0400

    Make EAttachment a little more thread-safe.
    
    EAttachment is now used from worker threads by EMailFormatterAttachment,
    so add some thread-safe accessor functions to eliminate potential races.
    
    Added thread-safe functions:
    
        e_attachment_dup_disposition()
        e_attachment_ref_file()
        e_attachment_ref_file_info()
        e_attachment_ref_icon()
        e_attachment_ref_mime_part()
        e_attachment_dup_description()
        e_attachment_dup_thumbnail_path()
    
    Renamed functions:
    
        e_attachment_get_mime_type() -> e_attachment_dup_mime_type()
    
    Removed non-thread-safe functions:
    
        e_attachment_get_file()
        e_attachment_get_file_info()
        e_attachment_get_icon()
        e_attachment_get_mime_part()
        e_attachment_get_description()
        e_attachment_get_thumbnail_path()

 calendar/gui/dialogs/comp-editor.c          |    7 +-
 e-util/e-attachment-button.c                |    8 +-
 e-util/e-attachment-dialog.c                |   21 ++-
 e-util/e-attachment-handler-image.c         |    2 +-
 e-util/e-attachment-store.c                 |   17 ++-
 e-util/e-attachment-view.c                  |    8 +-
 e-util/e-attachment.c                       |  250 +++++++++++++++++++--------
 e-util/e-attachment.h                       |   15 +-
 em-format/e-mail-formatter-attachment.c     |   12 +-
 em-format/e-mail-formatter-print.c          |   11 +-
 em-format/e-mail-parser.c                   |    4 +-
 modules/calendar/e-cal-attachment-handler.c |    4 +-
 modules/mail/e-mail-attachment-handler.c    |    8 +-
 13 files changed, 257 insertions(+), 110 deletions(-)
---
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 778e690..39ca3a8 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -3208,7 +3208,7 @@ attachment_loaded_cb (EAttachment *attachment,
         * So this is a lazy migration from the old form to the new.
         */
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
        if (file_info == NULL) {
                /* failed to load an attachment file */
                e_attachment_load_handle_error (attachment, result, parent);
@@ -3225,6 +3225,8 @@ attachment_loaded_cb (EAttachment *attachment,
                g_free (new_name);
        }
 
+       g_object_unref (file_info);
+
        e_attachment_load_handle_error (attachment, result, parent);
 }
 
@@ -3703,7 +3705,7 @@ comp_editor_get_mime_attach_list (CompEditor *editor)
 
                column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT;
                gtk_tree_model_get (model, &iter, column_id, &attachment, -1);
-               mime_part = e_attachment_get_mime_part (attachment);
+               mime_part = e_attachment_ref_mime_part (attachment);
                g_object_unref (attachment);
 
                valid = gtk_tree_model_iter_next (model, &iter);
@@ -3743,6 +3745,7 @@ comp_editor_get_mime_attach_list (CompEditor *editor)
 
                attach_list = g_slist_append (attach_list, cal_mime_attach);
 
+               g_object_unref (mime_part);
                g_object_unref (stream);
 
        }
diff --git a/e-util/e-attachment-button.c b/e-util/e-attachment-button.c
index 7778bb1..701b20e 100644
--- a/e-util/e-attachment-button.c
+++ b/e-util/e-attachment-button.c
@@ -277,7 +277,7 @@ attachment_button_expand_drag_data_get_cb (EAttachmentButton *button,
        attachment = e_attachment_button_get_attachment (button);
 
        if (attachment != NULL)
-               mime_type = e_attachment_get_mime_type (attachment);
+               mime_type = e_attachment_dup_mime_type (attachment);
 
        if (mime_type != NULL) {
                gboolean processed = FALSE;
@@ -290,7 +290,7 @@ attachment_button_expand_drag_data_get_cb (EAttachmentButton *button,
                if (g_strcmp0 (atom_name, mime_type) == 0) {
                        CamelMimePart *mime_part;
 
-                       mime_part = e_attachment_get_mime_part (attachment);
+                       mime_part = e_attachment_ref_mime_part (attachment);
 
                        if (mime_part != NULL) {
                                CamelDataWrapper *wrapper;
@@ -314,6 +314,8 @@ attachment_button_expand_drag_data_get_cb (EAttachmentButton *button,
                                processed = TRUE;
 
                                g_byte_array_free (buffer, TRUE);
+
+                               g_object_unref (mime_part);
                        }
                }
 
@@ -789,7 +791,7 @@ e_attachment_button_set_attachment (EAttachmentButton *button,
        if (attachment != NULL) {
                gchar *simple_type;
 
-               simple_type = e_attachment_get_mime_type (attachment);
+               simple_type = e_attachment_dup_mime_type (attachment);
                if (simple_type != NULL) {
                        GtkTargetEntry attach_entry[] = { { NULL, 0, 2 } };
 
diff --git a/e-util/e-attachment-dialog.c b/e-util/e-attachment-dialog.c
index 9a9a1e7..9102195 100644
--- a/e-util/e-attachment-dialog.c
+++ b/e-util/e-attachment-dialog.c
@@ -57,8 +57,8 @@ attachment_dialog_update (EAttachmentDialog *dialog)
        GtkWidget *widget;
        const gchar *content_type;
        const gchar *display_name;
-       const gchar *description;
-       const gchar *disposition;
+       gchar *description;
+       gchar *disposition;
        gchar *type_description = NULL;
        gboolean sensitive;
        gboolean active;
@@ -66,9 +66,9 @@ attachment_dialog_update (EAttachmentDialog *dialog)
        attachment = e_attachment_dialog_get_attachment (dialog);
 
        if (attachment != NULL) {
-               file_info = e_attachment_get_file_info (attachment);
-               description = e_attachment_get_description (attachment);
-               disposition = e_attachment_get_disposition (attachment);
+               file_info = e_attachment_ref_file_info (attachment);
+               description = e_attachment_dup_description (attachment);
+               disposition = e_attachment_dup_disposition (attachment);
        } else {
                file_info = NULL;
                description = NULL;
@@ -120,7 +120,11 @@ attachment_dialog_update (EAttachmentDialog *dialog)
        gtk_widget_set_sensitive (widget, sensitive);
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active);
 
+       g_free (description);
+       g_free (disposition);
        g_free (type_description);
+
+       g_clear_object (&file_info);
 }
 
 static void
@@ -231,10 +235,10 @@ attachment_dialog_response (GtkDialog *dialog,
        g_return_if_fail (E_IS_ATTACHMENT (priv->attachment));
        attachment = priv->attachment;
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
        g_return_if_fail (G_IS_FILE_INFO (file_info));
 
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
 
        attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME;
        text = gtk_entry_get_text (GTK_ENTRY (priv->display_name_entry));
@@ -258,6 +262,9 @@ attachment_dialog_response (GtkDialog *dialog,
        if (mime_part != NULL)
                camel_mime_part_set_disposition (mime_part, text);
 
+       g_clear_object (&file_info);
+       g_clear_object (&mime_part);
+
        g_object_notify (G_OBJECT (attachment), "file-info");
 }
 
diff --git a/e-util/e-attachment-handler-image.c b/e-util/e-attachment-handler-image.c
index 602f001..f4b35e3 100644
--- a/e-util/e-attachment-handler-image.c
+++ b/e-util/e-attachment-handler-image.c
@@ -173,7 +173,7 @@ attachment_handler_image_update_actions_cb (EAttachmentView *view,
        if (e_attachment_get_saving (attachment))
                goto exit;
 
-       mime_type = e_attachment_get_mime_type (attachment);
+       mime_type = e_attachment_dup_mime_type (attachment);
        visible =
                (mime_type != NULL) &&
                (g_ascii_strncasecmp (mime_type, "image/", 6) == 0);
diff --git a/e-util/e-attachment-store.c b/e-util/e-attachment-store.c
index 8ea2f89..08d7dc4 100644
--- a/e-util/e-attachment-store.c
+++ b/e-util/e-attachment-store.c
@@ -405,9 +405,11 @@ e_attachment_store_get_total_size (EAttachmentStore *store)
                EAttachment *attachment = iter->data;
                GFileInfo *file_info;
 
-               file_info = e_attachment_get_file_info (attachment);
-               if (file_info != NULL)
+               file_info = e_attachment_ref_file_info (attachment);
+               if (file_info != NULL) {
                        total_size += g_file_info_get_size (file_info);
+                       g_object_unref (file_info);
+               }
        }
 
        g_list_foreach (list, (GFunc) g_object_unref, NULL);
@@ -556,13 +558,18 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
                const gchar *name = NULL;
 
                attachment = attachment_list->data;
-               file_info = e_attachment_get_file_info (attachment);
+               file_info = e_attachment_ref_file_info (attachment);
+
                if (file_info != NULL)
                        name = g_file_info_get_display_name (file_info);
+
                if (name == NULL)
                        /* Translators: Default attachment filename. */
                        name = _("attachment.dat");
+
                gtk_file_chooser_set_current_name (file_chooser, name);
+
+               g_clear_object (&file_info);
        }
 
        response = gtk_dialog_run (GTK_DIALOG (dialog));
@@ -728,7 +735,7 @@ e_attachment_store_get_uris_async (EAttachmentStore *store,
                EAttachment *attachment = iter->data;
                GFile *file;
 
-               file = e_attachment_get_file (attachment);
+               file = e_attachment_ref_file (attachment);
                if (file != NULL) {
                        gchar *uri;
 
@@ -738,6 +745,8 @@ e_attachment_store_get_uris_async (EAttachmentStore *store,
                        /* Mark the list node for deletion. */
                        trash = g_list_prepend (trash, iter);
                        g_object_unref (attachment);
+
+                       g_object_unref (file);
                }
        }
 
diff --git a/e-util/e-attachment-view.c b/e-util/e-attachment-view.c
index d078bd4..1fb868e 100644
--- a/e-util/e-attachment-view.c
+++ b/e-util/e-attachment-view.c
@@ -174,7 +174,7 @@ action_open_with_cb (GtkAction *action,
                E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, &attachment, -1);
        g_return_if_fail (E_IS_ATTACHMENT (attachment));
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
        g_return_if_fail (file_info != NULL);
 
        content_type = g_file_info_get_content_type (file_info);
@@ -192,6 +192,8 @@ action_open_with_cb (GtkAction *action,
                g_object_unref (app_info);
        }
 
+       g_object_unref (file_info);
+
        g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
        g_list_free (list);
 }
@@ -1560,7 +1562,7 @@ e_attachment_view_drag_begin (EAttachmentView *view,
                gint width, height;
 
                attachment = E_ATTACHMENT (priv->selected->data);
-               icon = e_attachment_get_icon (attachment);
+               icon = e_attachment_ref_icon (attachment);
                g_return_if_fail (icon != NULL);
 
                icon_theme = gtk_icon_theme_get_default ();
@@ -1587,6 +1589,8 @@ e_attachment_view_drag_begin (EAttachmentView *view,
 
                        gtk_icon_info_free (icon_info);
                }
+
+               g_object_unref (icon);
        }
 }
 
diff --git a/e-util/e-attachment.c b/e-util/e-attachment.c
index 9f758c5..10f2513 100644
--- a/e-util/e-attachment.c
+++ b/e-util/e-attachment.c
@@ -57,6 +57,8 @@
 #define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*"
 
 struct _EAttachmentPrivate {
+       GMutex property_lock;
+
        GFile *file;
        GIcon *icon;
        GFileInfo *file_info;
@@ -117,7 +119,7 @@ create_system_thumbnail (EAttachment *attachment,
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE);
        g_return_val_if_fail (icon != NULL, FALSE);
 
-       file = e_attachment_get_file (attachment);
+       file = e_attachment_ref_file (attachment);
        if (file != NULL)
                file_path = g_file_get_path (file);
 
@@ -142,12 +144,14 @@ create_system_thumbnail (EAttachment *attachment,
                GFileInfo *file_info;
                const gchar *attribute;
 
-               file_info = e_attachment_get_file_info (attachment);
+               file_info = e_attachment_ref_file_info (attachment);
                attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH;
 
-               if (file_info != NULL)
+               if (file_info != NULL) {
                        g_file_info_set_attribute_byte_string (
                                file_info, attribute, thumbnail);
+                       g_object_unref (file_info);
+               }
        }
 
        g_free (thumbnail);
@@ -155,6 +159,8 @@ create_system_thumbnail (EAttachment *attachment,
        success = TRUE;
 
 exit:
+       g_clear_object (&file);
+
        return success;
 }
 
@@ -198,10 +204,10 @@ attachment_update_file_info_columns (EAttachment *attachment)
        GtkTreeIter iter;
        GFileInfo *file_info;
        const gchar *content_type;
-       const gchar *description;
        const gchar *display_name;
        gchar *content_desc;
        gchar *display_size;
+       gchar *description;
        gchar *caption;
        goffset size;
 
@@ -209,7 +215,7 @@ attachment_update_file_info_columns (EAttachment *attachment)
        if (!gtk_tree_row_reference_valid (reference))
                return;
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
        if (file_info == NULL)
                return;
 
@@ -225,9 +231,11 @@ attachment_update_file_info_columns (EAttachment *attachment)
        content_desc = g_content_type_get_description (content_type);
        display_size = g_format_size (size);
 
-       description = e_attachment_get_description (attachment);
-       if (description == NULL || *description == '\0')
-               description = display_name;
+       description = e_attachment_dup_description (attachment);
+       if (description == NULL || *description == '\0') {
+               g_free (description);
+               description = g_strdup (display_name);
+       }
 
        if (size > 0)
                caption = g_strdup_printf (
@@ -245,7 +253,10 @@ attachment_update_file_info_columns (EAttachment *attachment)
 
        g_free (content_desc);
        g_free (display_size);
+       g_free (description);
        g_free (caption);
+
+       g_clear_object (&file_info);
 }
 
 static void
@@ -271,7 +282,7 @@ attachment_update_icon_column (EAttachment *attachment)
        gtk_tree_path_free (path);
 
        cancellable = attachment->priv->cancellable;
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
 
        if (file_info != NULL) {
                icon = g_file_info_get_icon (file_info);
@@ -374,6 +385,8 @@ attachment_update_icon_column (EAttachment *attachment)
                g_object_unref (attachment->priv->icon);
        attachment->priv->icon = icon;
        g_object_notify (G_OBJECT (attachment), "icon");
+
+       g_clear_object (&file_info);
 }
 
 static void
@@ -587,23 +600,23 @@ attachment_get_property (GObject *object,
                        return;
 
                case PROP_FILE:
-                       g_value_set_object (
+                       g_value_take_object (
                                value,
-                               e_attachment_get_file (
+                               e_attachment_ref_file (
                                E_ATTACHMENT (object)));
                        return;
 
                case PROP_FILE_INFO:
-                       g_value_set_object (
+                       g_value_take_object (
                                value,
-                               e_attachment_get_file_info (
+                               e_attachment_ref_file_info (
                                E_ATTACHMENT (object)));
                        return;
 
                case PROP_ICON:
-                       g_value_set_object (
+                       g_value_take_object (
                                value,
-                               e_attachment_get_icon (
+                               e_attachment_ref_icon (
                                E_ATTACHMENT (object)));
                        return;
 
@@ -622,9 +635,9 @@ attachment_get_property (GObject *object,
                        return;
 
                case PROP_MIME_PART:
-                       g_value_set_object (
+                       g_value_take_object (
                                value,
-                               e_attachment_get_mime_part (
+                               e_attachment_ref_mime_part (
                                E_ATTACHMENT (object)));
                        return;
 
@@ -693,6 +706,8 @@ attachment_finalize (GObject *object)
 
        priv = E_ATTACHMENT_GET_PRIVATE (object);
 
+       g_mutex_clear (&priv->property_lock);
+
        g_free (priv->disposition);
 
        /* Chain up to parent's finalize() method. */
@@ -865,6 +880,8 @@ e_attachment_init (EAttachment *attachment)
        attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE;
        attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE;
 
+       g_mutex_init (&attachment->priv->property_lock);
+
        g_signal_connect (
                attachment, "notify::encrypted",
                G_CALLBACK (attachment_update_icon_column), NULL);
@@ -1005,7 +1022,7 @@ e_attachment_add_to_multipart (EAttachment *attachment,
        g_return_if_fail (CAMEL_IS_MULTIPART (multipart));
 
        /* Still loading?  Too bad. */
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
        if (mime_part == NULL)
                return;
 
@@ -1076,6 +1093,8 @@ e_attachment_add_to_multipart (EAttachment *attachment,
 
 exit:
        camel_multipart_add_part (multipart, mime_part);
+
+       g_clear_object (&mime_part);
 }
 
 void
@@ -1113,24 +1132,55 @@ e_attachment_get_disposition (EAttachment *attachment)
        return attachment->priv->disposition;
 }
 
+gchar *
+e_attachment_dup_disposition (EAttachment *attachment)
+{
+       const gchar *protected;
+       gchar *duplicate;
+
+       g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
+
+       g_mutex_lock (&attachment->priv->property_lock);
+
+       protected = e_attachment_get_disposition (attachment);
+       duplicate = g_strdup (protected);
+
+       g_mutex_unlock (&attachment->priv->property_lock);
+
+       return duplicate;
+}
+
 void
 e_attachment_set_disposition (EAttachment *attachment,
                               const gchar *disposition)
 {
        g_return_if_fail (E_IS_ATTACHMENT (attachment));
 
+       g_mutex_lock (&attachment->priv->property_lock);
+
        g_free (attachment->priv->disposition);
        attachment->priv->disposition = g_strdup (disposition);
 
+       g_mutex_unlock (&attachment->priv->property_lock);
+
        g_object_notify (G_OBJECT (attachment), "disposition");
 }
 
 GFile *
-e_attachment_get_file (EAttachment *attachment)
+e_attachment_ref_file (EAttachment *attachment)
 {
+       GFile *file = NULL;
+
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       return attachment->priv->file;
+       g_mutex_lock (&attachment->priv->property_lock);
+
+       if (attachment->priv->file != NULL)
+               file = g_object_ref (attachment->priv->file);
+
+       g_mutex_unlock (&attachment->priv->property_lock);
+
+       return file;
 }
 
 void
@@ -1144,20 +1194,31 @@ e_attachment_set_file (EAttachment *attachment,
                g_object_ref (file);
        }
 
-       if (attachment->priv->file != NULL)
-               g_object_unref (attachment->priv->file);
+       g_mutex_lock (&attachment->priv->property_lock);
 
+       g_clear_object (&attachment->priv->file);
        attachment->priv->file = file;
 
+       g_mutex_unlock (&attachment->priv->property_lock);
+
        g_object_notify (G_OBJECT (attachment), "file");
 }
 
 GFileInfo *
-e_attachment_get_file_info (EAttachment *attachment)
+e_attachment_ref_file_info (EAttachment *attachment)
 {
+       GFileInfo *file_info = NULL;
+
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       return attachment->priv->file_info;
+       g_mutex_lock (&attachment->priv->property_lock);
+
+       if (attachment->priv->file_info != NULL)
+               file_info = g_object_ref (attachment->priv->file_info);
+
+       g_mutex_unlock (&attachment->priv->property_lock);
+
+       return file_info;
 }
 
 void
@@ -1195,7 +1256,7 @@ e_attachment_set_file_info (EAttachment *attachment,
 }
 
 /**
- * e_attachment_get_mime_type:
+ * e_attachment_dup_mime_type:
  * @attachment: an #EAttachment
  *
  * Returns the MIME type of @attachment according to its #GFileInfo.
@@ -1205,37 +1266,44 @@ e_attachment_set_file_info (EAttachment *attachment,
  * Returns: a newly-allocated MIME type string, or %NULL
  **/
 gchar *
-e_attachment_get_mime_type (EAttachment *attachment)
+e_attachment_dup_mime_type (EAttachment *attachment)
 {
        GFileInfo *file_info;
-       const gchar *content_type;
-       gchar *mime_type;
+       const gchar *content_type = NULL;
+       gchar *mime_type = NULL;
 
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       file_info = e_attachment_get_file_info (attachment);
-       if (file_info == NULL)
-               return NULL;
+       file_info = e_attachment_ref_file_info (attachment);
+       if (file_info != NULL)
+               content_type = g_file_info_get_content_type (file_info);
 
-       content_type = g_file_info_get_content_type (file_info);
-       if (content_type == NULL)
-               return NULL;
+       if (content_type != NULL)
+               mime_type = g_content_type_get_mime_type (content_type);
 
-       mime_type = g_content_type_get_mime_type (content_type);
-       if (!mime_type)
-               return NULL;
+       if (mime_type != NULL)
+               camel_strdown (mime_type);
 
-       camel_strdown (mime_type);
+       g_clear_object (&file_info);
 
        return mime_type;
 }
 
 GIcon *
-e_attachment_get_icon (EAttachment *attachment)
+e_attachment_ref_icon (EAttachment *attachment)
 {
+       GIcon *icon = NULL;
+
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       return attachment->priv->icon;
+       g_mutex_lock (&attachment->priv->property_lock);
+
+       if (attachment->priv->icon != NULL)
+               icon = g_object_ref (attachment->priv->icon);
+
+       g_mutex_unlock (&attachment->priv->property_lock);
+
+       return icon;
 }
 
 gboolean
@@ -1247,11 +1315,20 @@ e_attachment_get_loading (EAttachment *attachment)
 }
 
 CamelMimePart *
-e_attachment_get_mime_part (EAttachment *attachment)
+e_attachment_ref_mime_part (EAttachment *attachment)
 {
+       CamelMimePart *mime_part = NULL;
+
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       return attachment->priv->mime_part;
+       g_mutex_lock (&attachment->priv->property_lock);
+
+       if (attachment->priv->mime_part != NULL)
+               mime_part = g_object_ref (attachment->priv->mime_part);
+
+       g_mutex_unlock (&attachment->priv->property_lock);
+
+       return mime_part;
 }
 
 void
@@ -1265,11 +1342,13 @@ e_attachment_set_mime_part (EAttachment *attachment,
                g_object_ref (mime_part);
        }
 
-       if (attachment->priv->mime_part != NULL)
-               g_object_unref (attachment->priv->mime_part);
+       g_mutex_lock (&attachment->priv->property_lock);
 
+       g_clear_object (&attachment->priv->mime_part);
        attachment->priv->mime_part = mime_part;
 
+       g_mutex_unlock (&attachment->priv->property_lock);
+
        g_object_notify (G_OBJECT (attachment), "mime-part");
 }
 
@@ -1373,38 +1452,50 @@ e_attachment_set_signed (EAttachment *attachment,
        g_object_notify (G_OBJECT (attachment), "signed");
 }
 
-const gchar *
-e_attachment_get_description (EAttachment *attachment)
+gchar *
+e_attachment_dup_description (EAttachment *attachment)
 {
        GFileInfo *file_info;
        const gchar *attribute;
+       const gchar *protected;
+       gchar *duplicate;
 
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION;
-       file_info = e_attachment_get_file_info (attachment);
-
+       file_info = e_attachment_ref_file_info (attachment);
        if (file_info == NULL)
                return NULL;
 
-       return g_file_info_get_attribute_string (file_info, attribute);
+       attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION;
+       protected = g_file_info_get_attribute_string (file_info, attribute);
+       duplicate = g_strdup (protected);
+
+       g_object_unref (file_info);
+
+       return duplicate;
 }
 
-const gchar *
-e_attachment_get_thumbnail_path (EAttachment *attachment)
+gchar *
+e_attachment_dup_thumbnail_path (EAttachment *attachment)
 {
        GFileInfo *file_info;
        const gchar *attribute;
+       const gchar *protected;
+       gchar *duplicate;
 
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH;
-       file_info = e_attachment_get_file_info (attachment);
-
+       file_info = e_attachment_ref_file_info (attachment);
        if (file_info == NULL)
                return NULL;
 
-       return g_file_info_get_attribute_byte_string (file_info, attribute);
+       attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH;
+       protected = g_file_info_get_attribute_string (file_info, attribute);
+       duplicate = g_strdup (protected);
+
+       g_object_unref (file_info);
+
+       return duplicate;
 }
 
 gboolean
@@ -1415,7 +1506,7 @@ e_attachment_is_rfc822 (EAttachment *attachment)
 
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE);
 
-       mime_type = e_attachment_get_mime_type (attachment);
+       mime_type = e_attachment_dup_mime_type (attachment);
        is_rfc822 =
                (mime_type != NULL) &&
                (g_ascii_strcasecmp (mime_type, "message/rfc822") == 0);
@@ -1437,7 +1528,7 @@ e_attachment_list_apps (EAttachment *attachment)
 
        g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
        if (file_info == NULL)
                return NULL;
 
@@ -1460,6 +1551,8 @@ e_attachment_list_apps (EAttachment *attachment)
        g_free (allocated);
 
 exit:
+       g_clear_object (&file_info);
+
        return app_info_list;
 }
 
@@ -1798,7 +1891,7 @@ attachment_load_from_mime_part_thread (GSimpleAsyncResult *simple,
        g_object_set_data (G_OBJECT (simple), ATTACHMENT_LOAD_CONTEXT, NULL);
 
        attachment = load_context->attachment;
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
 
        file_info = g_file_info_new ();
        load_context->file_info = file_info;
@@ -1902,6 +1995,8 @@ attachment_load_from_mime_part_thread (GSimpleAsyncResult *simple,
        g_simple_async_result_set_op_res_gpointer (
                simple, load_context,
                (GDestroyNotify) attachment_load_context_free);
+
+       g_clear_object (&mime_part);
 }
 
 void
@@ -1932,8 +2027,8 @@ e_attachment_load_async (EAttachment *attachment,
                return;
        }
 
-       file = e_attachment_get_file (attachment);
-       mime_part = e_attachment_get_mime_part (attachment);
+       file = e_attachment_ref_file (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
        g_return_if_fail (file != NULL || mime_part != NULL);
 
        load_context = attachment_load_context_new (
@@ -1960,6 +2055,9 @@ e_attachment_load_async (EAttachment *attachment,
                        G_PRIORITY_DEFAULT,
                        cancellable);
        }
+
+       g_clear_object (&file);
+       g_clear_object (&mime_part);
 }
 
 gboolean
@@ -2033,7 +2131,7 @@ e_attachment_load_handle_error (EAttachment *attachment,
                return;
        }
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
 
        if (file_info != NULL)
                display_name = g_file_info_get_display_name (file_info);
@@ -2047,6 +2145,8 @@ e_attachment_load_handle_error (EAttachment *attachment,
                primary_text = g_strdup_printf (
                        _("Could not load the attachment"));
 
+       g_clear_object (&file_info);
+
        dialog = gtk_message_dialog_new_with_markup (
                parent, GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
@@ -2274,8 +2374,8 @@ e_attachment_open_async (EAttachment *attachment,
 
        g_return_if_fail (E_IS_ATTACHMENT (attachment));
 
-       file = e_attachment_get_file (attachment);
-       mime_part = e_attachment_get_mime_part (attachment);
+       file = e_attachment_ref_file (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
        g_return_if_fail (file != NULL || mime_part != NULL);
 
        open_context = attachment_open_context_new (
@@ -2292,6 +2392,9 @@ e_attachment_open_async (EAttachment *attachment,
 
        } else if (mime_part != NULL)
                attachment_open_save_temporary (open_context);
+
+       g_clear_object (&file);
+       g_clear_object (&mime_part);
 }
 
 gboolean
@@ -2334,7 +2437,7 @@ e_attachment_open_handle_error (EAttachment *attachment,
        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
                return;
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
 
        if (file_info != NULL)
                display_name = g_file_info_get_display_name (file_info);
@@ -2348,6 +2451,8 @@ e_attachment_open_handle_error (EAttachment *attachment,
                primary_text = g_strdup_printf (
                        _("Could not open the attachment"));
 
+       g_clear_object (&file_info);
+
        dialog = gtk_message_dialog_new_with_markup (
                parent, GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
@@ -2480,7 +2585,7 @@ attachment_save_new_candidate (SaveContext *save_context)
        gchar *basename;
 
        attachment = save_context->attachment;
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
 
        if (file_info != NULL)
                display_name = g_file_info_get_display_name (file_info);
@@ -2516,6 +2621,8 @@ attachment_save_new_candidate (SaveContext *save_context)
 
        g_free (basename);
 
+       g_clear_object (&file_info);
+
        return candidate;
 }
 
@@ -2630,7 +2737,7 @@ attachment_save_got_output_stream (SaveContext *save_context)
 
        attachment = save_context->attachment;
        cancellable = attachment->priv->cancellable;
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
 
        /* Decode the MIME part to an in-memory buffer.  We have to do
         * this because CamelStream is synchronous-only, and using threads
@@ -2661,6 +2768,8 @@ attachment_save_got_output_stream (SaveContext *save_context)
                G_PRIORITY_DEFAULT, cancellable,
                (GAsyncReadyCallback) attachment_save_read_cb,
                save_context);
+
+       g_clear_object (&mime_part);
 }
 
 static void
@@ -2800,7 +2909,8 @@ e_attachment_save_async (EAttachment *attachment,
                return;
        }
 
-       if (e_attachment_get_mime_part (attachment) == NULL) {
+       /* Just peek, don't reference. */
+       if (attachment->priv->mime_part == NULL) {
                g_simple_async_report_error_in_idle (
                        G_OBJECT (attachment), callback, user_data,
                        G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
@@ -2871,7 +2981,7 @@ e_attachment_save_handle_error (EAttachment *attachment,
        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
                return;
 
-       file_info = e_attachment_get_file_info (attachment);
+       file_info = e_attachment_ref_file_info (attachment);
 
        if (file_info != NULL)
                display_name = g_file_info_get_display_name (file_info);
@@ -2885,6 +2995,8 @@ e_attachment_save_handle_error (EAttachment *attachment,
                primary_text = g_strdup_printf (
                        _("Could not save the attachment"));
 
+       g_clear_object (&file_info);
+
        dialog = gtk_message_dialog_new_with_markup (
                parent, GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
diff --git a/e-util/e-attachment.h b/e-util/e-attachment.h
index 0da2c9d..b21a0f2 100644
--- a/e-util/e-attachment.h
+++ b/e-util/e-attachment.h
@@ -76,18 +76,19 @@ gboolean    e_attachment_get_can_show       (EAttachment *attachment);
 void           e_attachment_set_can_show       (EAttachment *attachment,
                                                 gboolean can_show);
 const gchar *  e_attachment_get_disposition    (EAttachment *attachment);
+gchar *                e_attachment_dup_disposition    (EAttachment *attachment);
 void           e_attachment_set_disposition    (EAttachment *attachment,
                                                 const gchar *disposition);
-GFile *                e_attachment_get_file           (EAttachment *attachment);
+GFile *                e_attachment_ref_file           (EAttachment *attachment);
 void           e_attachment_set_file           (EAttachment *attachment,
                                                 GFile *file);
-GFileInfo *    e_attachment_get_file_info      (EAttachment *attachment);
+GFileInfo *    e_attachment_ref_file_info      (EAttachment *attachment);
 void           e_attachment_set_file_info      (EAttachment *attachment,
                                                 GFileInfo *file_info);
-gchar *                e_attachment_get_mime_type      (EAttachment *attachment);
-GIcon *                e_attachment_get_icon           (EAttachment *attachment);
+gchar *                e_attachment_dup_mime_type      (EAttachment *attachment);
+GIcon *                e_attachment_ref_icon           (EAttachment *attachment);
 gboolean       e_attachment_get_loading        (EAttachment *attachment);
-CamelMimePart *        e_attachment_get_mime_part      (EAttachment *attachment);
+CamelMimePart *        e_attachment_ref_mime_part      (EAttachment *attachment);
 void           e_attachment_set_mime_part      (EAttachment *attachment,
                                                 CamelMimePart *mime_part);
 gint           e_attachment_get_percent        (EAttachment *attachment);
@@ -107,8 +108,8 @@ camel_cipher_validity_sign_t
                e_attachment_get_signed         (EAttachment *attachment);
 void           e_attachment_set_signed         (EAttachment *attachment,
                                                 camel_cipher_validity_sign_t signed_);
-const gchar *  e_attachment_get_description    (EAttachment *attachment);
-const gchar *  e_attachment_get_thumbnail_path (EAttachment *attachment);
+gchar *                e_attachment_dup_description    (EAttachment *attachment);
+gchar *                e_attachment_dup_thumbnail_path (EAttachment *attachment);
 gboolean       e_attachment_is_rfc822          (EAttachment *attachment);
 GList *                e_attachment_list_apps          (EAttachment *attachment);
 
diff --git a/em-format/e-mail-formatter-attachment.c b/em-format/e-mail-formatter-attachment.c
index 1003b55..fb997c0 100644
--- a/em-format/e-mail-formatter-attachment.c
+++ b/em-format/e-mail-formatter-attachment.c
@@ -198,17 +198,17 @@ emfe_attachment_format (EMailFormatterExtension *extension,
                if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
                        gchar *name;
                        EAttachment *attachment;
-                       GFileInfo *fi;
-                       const gchar *description;
+                       GFileInfo *file_info;
                        const gchar *display_name;
+                       gchar *description;
 
                        attachment = e_mail_part_attachment_ref_attachment (
                                E_MAIL_PART_ATTACHMENT (part));
 
-                       fi = e_attachment_get_file_info (attachment);
-                       display_name = g_file_info_get_display_name (fi);
+                       file_info = e_attachment_ref_file_info (attachment);
+                       display_name = g_file_info_get_display_name (file_info);
 
-                       description = e_attachment_get_description (attachment);
+                       description = e_attachment_dup_description (attachment);
                        if (description != NULL && *description != '\0') {
                                name = g_strdup_printf (
                                        "<h2>Attachment: %s (%s)</h2>\n",
@@ -222,9 +222,11 @@ emfe_attachment_format (EMailFormatterExtension *extension,
                        camel_stream_write_string (
                                stream, name, cancellable, NULL);
 
+                       g_free (description);
                        g_free (name);
 
                        g_object_unref (attachment);
+                       g_object_unref (file_info);
                }
 
                for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) {
diff --git a/em-format/e-mail-formatter-print.c b/em-format/e-mail-formatter-print.c
index 0728cb6..4d5c303 100644
--- a/em-format/e-mail-formatter-print.c
+++ b/em-format/e-mail-formatter-print.c
@@ -57,20 +57,21 @@ mail_formatter_print_write_attachments (EMailFormatter *formatter,
                EMailPartAttachment *part;
                EAttachment *attachment;
                GFileInfo *file_info;
-               gchar *name, *size;
-               const gchar *description;
                const gchar *display_name;
+               gchar *description;
+               gchar *name;
+               gchar *size;
 
                part = g_queue_pop_head (attachments);
                attachment = e_mail_part_attachment_ref_attachment (part);
 
-               file_info = e_attachment_get_file_info (attachment);
+               file_info = e_attachment_ref_file_info (attachment);
                if (file_info == NULL) {
                        g_object_unref (attachment);
                        continue;
                }
 
-               description = e_attachment_get_description (attachment);
+               description = e_attachment_dup_description (attachment);
                display_name = g_file_info_get_display_name (file_info);
 
                if (description != NULL && *description != '\0') {
@@ -86,10 +87,12 @@ mail_formatter_print_write_attachments (EMailFormatter *formatter,
                        str, "<tr><td>%s</td><td>%s</td></tr>\n",
                        name, size);
 
+               g_free (description);
                g_free (name);
                g_free (size);
 
                g_object_unref (attachment);
+               g_object_unref (file_info);
        }
 
        g_string_append (str, "</table>\n");
diff --git a/em-format/e-mail-parser.c b/em-format/e-mail-parser.c
index f31e0ca..57c362e 100644
--- a/em-format/e-mail-parser.c
+++ b/em-format/e-mail-parser.c
@@ -734,14 +734,12 @@ e_mail_parser_wrap_as_attachment (EMailParser *parser,
        if (size != 0) {
                GFileInfo *file_info;
 
-               file_info = e_attachment_get_file_info (attachment);
+               file_info = e_attachment_ref_file_info (attachment);
 
                if (file_info == NULL) {
                        file_info = g_file_info_new ();
                        g_file_info_set_content_type (
                                file_info, empa->snoop_mime_type);
-               } else {
-                       g_object_ref (file_info);
                }
 
                g_file_info_set_size (file_info, size);
diff --git a/modules/calendar/e-cal-attachment-handler.c b/modules/calendar/e-cal-attachment-handler.c
index 343d4ba..8613fbf 100644
--- a/modules/calendar/e-cal-attachment-handler.c
+++ b/modules/calendar/e-cal-attachment-handler.c
@@ -79,7 +79,7 @@ attachment_handler_get_component (EAttachment *attachment)
            e_attachment_get_saving (attachment))
                return NULL;
 
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
        if (mime_part == NULL)
                return NULL;
 
@@ -90,6 +90,8 @@ attachment_handler_get_component (EAttachment *attachment)
        camel_data_wrapper_decode_to_stream_sync (wrapper, stream, NULL, NULL);
        g_object_unref (stream);
 
+       g_object_unref (mime_part);
+
        if (buffer->len > 0) {
                const gchar *str;
 
diff --git a/modules/mail/e-mail-attachment-handler.c b/modules/mail/e-mail-attachment-handler.c
index d041bc9..5e328c4 100644
--- a/modules/mail/e-mail-attachment-handler.c
+++ b/modules/mail/e-mail-attachment-handler.c
@@ -79,7 +79,7 @@ mail_attachment_handler_get_selected_message (EAttachmentHandler *handler)
        g_return_val_if_fail (g_list_length (selected) == 1, NULL);
 
        attachment = E_ATTACHMENT (selected->data);
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
 
        outer_wrapper =
                camel_medium_get_content (CAMEL_MEDIUM (mime_part));
@@ -128,6 +128,8 @@ exit:
        if (message == NULL)
                message = g_object_ref (outer_wrapper);
 
+       g_clear_object (&mime_part);
+
        g_list_free_full (selected, (GDestroyNotify) g_object_unref);
 
        return message;
@@ -477,7 +479,7 @@ mail_attachment_handler_update_actions (EAttachmentView *view,
            e_attachment_get_saving (attachment))
                goto exit;
 
-       mime_part = e_attachment_get_mime_part (attachment);
+       mime_part = e_attachment_ref_mime_part (attachment);
 
        if (mime_part != NULL) {
                CamelMedium *medium;
@@ -486,6 +488,8 @@ mail_attachment_handler_update_actions (EAttachmentView *view,
                medium = CAMEL_MEDIUM (mime_part);
                content = camel_medium_get_content (medium);
                visible = CAMEL_IS_MIME_MESSAGE (content);
+
+               g_object_unref (mime_part);
        }
 
 exit:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]