[evolution] Bug 790635 - Slow start with 10+ mail accounts enabled



commit f5ac358916eca454183341c7b4497361a8ab8e0b
Author: Milan Crha <mcrha redhat com>
Date:   Thu Nov 30 09:49:22 2017 +0100

    Bug 790635 - Slow start with 10+ mail accounts enabled

 src/composer/e-msg-composer.c           |    2 +-
 src/e-util/e-mail-signature-editor.c    |    2 +-
 src/e-util/e-simple-async-result.c      |   58 ++++++++++++++++++++++++++++++-
 src/e-util/e-simple-async-result.h      |   12 ++++++-
 src/libemail-engine/mail-folder-cache.c |   43 +++++++++++------------
 5 files changed, 91 insertions(+), 26 deletions(-)
---
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index a71a7e1..43fd974 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -2770,7 +2770,7 @@ e_msg_composer_editor_created_cb (GObject *source_object,
                g_warning ("%s: Failed to create HTML editor: %s", G_STRFUNC, error->message);
                g_clear_error (&error);
        } else {
-               e_simple_async_result_set_op_pointer (eresult, editor);
+               e_simple_async_result_set_op_pointer (eresult, editor, NULL);
                e_simple_async_result_complete (eresult);
        }
 
diff --git a/src/e-util/e-mail-signature-editor.c b/src/e-util/e-mail-signature-editor.c
index 6be609f..1919519 100644
--- a/src/e-util/e-mail-signature-editor.c
+++ b/src/e-util/e-mail-signature-editor.c
@@ -758,7 +758,7 @@ mail_signature_editor_html_editor_created_cb (GObject *source_object,
 
        g_object_ref (signature_editor);
 
-       e_simple_async_result_set_op_pointer (eresult, signature_editor);
+       e_simple_async_result_set_op_pointer (eresult, signature_editor, NULL);
 
        e_simple_async_result_complete (eresult);
 
diff --git a/src/e-util/e-simple-async-result.c b/src/e-util/e-simple-async-result.c
index 89423f2..81f50d6 100644
--- a/src/e-util/e-simple-async-result.c
+++ b/src/e-util/e-simple-async-result.c
@@ -30,6 +30,9 @@ struct _ESimpleAsyncResultPrivate {
        GDestroyNotify destroy_user_data;
 
        gpointer op_pointer;
+       GDestroyNotify destroy_op_pointer;
+
+       GError *error;
 };
 
 static void e_simple_async_result_iface_init (GAsyncResultIface *iface);
@@ -93,7 +96,14 @@ e_simple_async_result_finalize (GObject *object)
        result->priv->destroy_user_data = NULL;
        result->priv->user_data = NULL;
 
+       if (result->priv->op_pointer && result->priv->destroy_op_pointer)
+               result->priv->destroy_op_pointer (result->priv->op_pointer);
+
+       result->priv->destroy_op_pointer = NULL;
+       result->priv->op_pointer = NULL;
+
        g_clear_object (&result->priv->source_object);
+       g_clear_error (&result->priv->error);
 
        /* Chain up to parent's method */
        G_OBJECT_CLASS (e_simple_async_result_parent_class)->finalize (object);
@@ -137,6 +147,17 @@ e_simple_async_result_new (GObject *source_object,
        return result;
 }
 
+gboolean
+e_simple_async_result_is_valid (GAsyncResult *result,
+                               GObject *source,
+                               gpointer source_tag)
+{
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+       return g_async_result_get_source_object (result) == source &&
+              g_async_result_is_tagged (result, source_tag);
+}
+
 void
 e_simple_async_result_set_user_data (ESimpleAsyncResult *result,
                                     gpointer user_data,
@@ -190,11 +211,19 @@ e_simple_async_result_steal_user_data (ESimpleAsyncResult *result)
 
 void
 e_simple_async_result_set_op_pointer (ESimpleAsyncResult *result,
-                                     gpointer ptr)
+                                     gpointer ptr,
+                                     GDestroyNotify destroy_ptr)
 {
        g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result));
 
+       if (result->priv->op_pointer == ptr)
+               return;
+
+       if (result->priv->op_pointer && result->priv->destroy_op_pointer)
+               result->priv->destroy_op_pointer (result->priv->op_pointer);
+
        result->priv->op_pointer = ptr;
+       result->priv->destroy_op_pointer = destroy_ptr;
 }
 
 gpointer
@@ -321,6 +350,33 @@ e_simple_async_result_complete_idle (ESimpleAsyncResult *result)
 }
 
 void
+e_simple_async_result_take_error (ESimpleAsyncResult *result,
+                                 GError *error)
+{
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result));
+
+       if (error != result->priv->error) {
+               g_clear_error (&result->priv->error);
+               result->priv->error = error;
+       }
+}
+
+gboolean
+e_simple_async_result_propagate_error (ESimpleAsyncResult *result,
+                                      GError **error)
+{
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+       if (!result->priv->error)
+               return FALSE;
+
+       if (error)
+               g_propagate_error (error, g_error_copy (result->priv->error));
+
+       return TRUE;
+}
+
+void
 e_simple_async_result_free_global_memory (void)
 {
        G_LOCK (thread_pool);
diff --git a/src/e-util/e-simple-async-result.h b/src/e-util/e-simple-async-result.h
index 8319e96..a53a6ce 100644
--- a/src/e-util/e-simple-async-result.h
+++ b/src/e-util/e-simple-async-result.h
@@ -74,6 +74,9 @@ ESimpleAsyncResult *
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data,
                                                 gpointer source_tag);
+gboolean       e_simple_async_result_is_valid  (GAsyncResult *result,
+                                                GObject *source,
+                                                gpointer source_tag);
 void           e_simple_async_result_set_user_data
                                                (ESimpleAsyncResult *result,
                                                 gpointer user_data,
@@ -84,7 +87,8 @@ gpointer      e_simple_async_result_steal_user_data
                                                (ESimpleAsyncResult *result);
 void           e_simple_async_result_set_op_pointer
                                                (ESimpleAsyncResult *result,
-                                                gpointer ptr);
+                                                gpointer ptr,
+                                                GDestroyNotify destroy_ptr);
 gpointer       e_simple_async_result_get_op_pointer
                                                (ESimpleAsyncResult *result);
 void           e_simple_async_result_run_in_thread
@@ -95,6 +99,12 @@ void         e_simple_async_result_run_in_thread
 void           e_simple_async_result_complete  (ESimpleAsyncResult *result);
 void           e_simple_async_result_complete_idle
                                                (ESimpleAsyncResult *result);
+void           e_simple_async_result_take_error
+                                               (ESimpleAsyncResult *result,
+                                                GError *error);
+gboolean       e_simple_async_result_propagate_error
+                                               (ESimpleAsyncResult *result,
+                                                GError **error);
 void           e_simple_async_result_free_global_memory
                                                (void);
 
diff --git a/src/libemail-engine/mail-folder-cache.c b/src/libemail-engine/mail-folder-cache.c
index 7282615..62c01a1 100644
--- a/src/libemail-engine/mail-folder-cache.c
+++ b/src/libemail-engine/mail-folder-cache.c
@@ -38,8 +38,9 @@
 
 #include <libedataserver/libedataserver.h>
 
-#include <libemail-engine/mail-mt.h>
+#include "e-util/e-util.h"
 
+#include "mail-mt.h"
 #include "mail-folder-cache.h"
 #include "mail-ops.h"
 #include "e-mail-utils.h"
@@ -2056,8 +2057,8 @@ mail_folder_cache_first_update (MailFolderCache *cache,
 
 /* Helper for mail_folder_cache_note_store() */
 static void
-mail_folder_cache_note_store_thread (GSimpleAsyncResult *simple,
-                                     GObject *source_object,
+mail_folder_cache_note_store_thread (ESimpleAsyncResult *simple,
+                                     gpointer source_object,
                                      GCancellable *cancellable)
 {
        MailFolderCache *cache;
@@ -2070,7 +2071,7 @@ mail_folder_cache_note_store_thread (GSimpleAsyncResult *simple,
        GError *local_error = NULL;
 
        cache = MAIL_FOLDER_CACHE (source_object);
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+       async_context = e_simple_async_result_get_op_pointer (simple);
        store_info = async_context->store_info;
 
        service = CAMEL_SERVICE (store_info->store);
@@ -2125,7 +2126,7 @@ mail_folder_cache_note_store_thread (GSimpleAsyncResult *simple,
 
        if (local_error != NULL) {
                g_warn_if_fail (async_context->info == NULL);
-               g_simple_async_result_take_error (simple, local_error);
+               e_simple_async_result_take_error (simple, local_error);
                goto exit;
        }
 
@@ -2153,15 +2154,15 @@ exit:
        g_mutex_unlock (&store_info->lock);
 
        while (!g_queue_is_empty (&result_queue)) {
-               GSimpleAsyncResult *queued_result;
+               ESimpleAsyncResult *queued_result;
 
                queued_result = g_queue_pop_head (&result_queue);
 
-               /* Skip the GSimpleAsyncResult passed into this function.
-                * g_simple_async_result_run_in_thread() will complete it
+               /* Skip the ESimpleAsyncResult passed into this function.
+                * e_simple_async_result_run_in_thread() will complete it
                 * for us, and we don't want to complete it twice. */
                if (queued_result != simple)
-                       g_simple_async_result_complete_in_idle (queued_result);
+                       e_simple_async_result_complete_idle (queued_result);
 
                g_clear_object (&queued_result);
        }
@@ -2184,7 +2185,7 @@ mail_folder_cache_note_store (MailFolderCache *cache,
                               gpointer user_data)
 {
        StoreInfo *store_info;
-       GSimpleAsyncResult *simple;
+       ESimpleAsyncResult *simple;
        AsyncContext *async_context;
 
        g_return_if_fail (MAIL_IS_FOLDER_CACHE (cache));
@@ -2197,13 +2198,11 @@ mail_folder_cache_note_store (MailFolderCache *cache,
        async_context = g_slice_new0 (AsyncContext);
        async_context->store_info = store_info_ref (store_info);
 
-       simple = g_simple_async_result_new (
+       simple = e_simple_async_result_new (
                G_OBJECT (cache), callback, user_data,
                mail_folder_cache_note_store);
 
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       g_simple_async_result_set_op_res_gpointer (
+       e_simple_async_result_set_op_pointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
        g_mutex_lock (&store_info->lock);
@@ -2219,10 +2218,10 @@ mail_folder_cache_note_store (MailFolderCache *cache,
         * this store in progress so we'll just pick up the result
         * when it finishes. */
        if (g_queue_get_length (&store_info->folderinfo_updates) == 1)
-               g_simple_async_result_run_in_thread (
-                       simple,
+               e_simple_async_result_run_in_thread (
+                       simple, G_PRIORITY_DEFAULT,
                        mail_folder_cache_note_store_thread,
-                       G_PRIORITY_DEFAULT, cancellable);
+                       cancellable);
 
        g_mutex_unlock (&store_info->lock);
 
@@ -2237,18 +2236,18 @@ mail_folder_cache_note_store_finish (MailFolderCache *cache,
                                      CamelFolderInfo **out_info,
                                      GError **error)
 {
-       GSimpleAsyncResult *simple;
+       ESimpleAsyncResult *simple;
        AsyncContext *async_context;
 
        g_return_val_if_fail (
-               g_simple_async_result_is_valid (
+               e_simple_async_result_is_valid (
                result, G_OBJECT (cache),
                mail_folder_cache_note_store), FALSE);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+       simple = E_SIMPLE_ASYNC_RESULT (result);
+       async_context = e_simple_async_result_get_op_pointer (simple);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (e_simple_async_result_propagate_error (simple, error))
                return FALSE;
 
        if (out_info != NULL) {


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