[evolution-data-server] Bug #728167 - [IMAPx] Message headers downloaded twice



commit 5a28c833bfcc38e46598f7147d9f3353cafe481c
Author: Milan Crha <mcrha redhat com>
Date:   Fri May 2 12:51:04 2014 +0200

    Bug #728167 - [IMAPx] Message headers downloaded twice

 camel/providers/imapx/camel-imapx-server.c |  121 ++++++++++++++++++----------
 camel/providers/imapx/camel-imapx-server.h |    6 ++
 camel/providers/imapx/camel-imapx-store.c  |   30 +++++++
 camel/providers/imapx/camel-imapx-store.h  |    8 ++
 4 files changed, 123 insertions(+), 42 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index b9624ef..8c63038 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -1793,34 +1793,31 @@ imapx_match_active_job (CamelIMAPXServer *is,
 }
 
 static CamelIMAPXJob *
-imapx_is_job_in_queue (CamelIMAPXServer *is,
-                       CamelIMAPXMailbox *mailbox,
-                       guint32 type,
-                       const gchar *uid)
+imapx_server_ref_job (CamelIMAPXServer *imapx_server,
+                     CamelIMAPXMailbox *mailbox,
+                     guint32 job_type,
+                     const gchar *uid)
 {
-       GList *head, *link;
-       CamelIMAPXJob *job = NULL;
-       gboolean found = FALSE;
+       CamelIMAPXStore *imapx_store;
+       CamelIMAPXJob *job;
 
-       QUEUE_LOCK (is);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), NULL);
 
-       head = g_queue_peek_head_link (&is->jobs);
+       /* first try its own queue */
+       job = camel_imapx_server_ref_job (imapx_server, mailbox, job_type, uid);
+       if (job)
+               return job;
 
-       for (link = head; link != NULL; link = g_list_next (link)) {
-               job = (CamelIMAPXJob *) link->data;
+       /* then try queue for all the opened servers */
+       imapx_store = camel_imapx_server_ref_store (imapx_server);
+       if (!imapx_store)
+               return NULL;
 
-               if (!job || !(job->type & type))
-                       continue;
+       job = camel_imapx_store_ref_job (imapx_store, mailbox, job_type, uid);
 
-               if (camel_imapx_job_matches (job, mailbox, uid)) {
-                       found = TRUE;
-                       break;
-               }
-       }
+       g_object_unref (imapx_store);
 
-       QUEUE_UNLOCK (is);
-
-       return found ? job : NULL;
+       return job;
 }
 
 static void
@@ -4009,24 +4006,17 @@ imapx_command_select_done (CamelIMAPXServer *is,
                        /* We don't want to fetch new messages if the command we selected this
                         * folder for is *already* fetching all messages (i.e. scan_changes).
                         * Bug #667725. */
-                       CamelIMAPXJob *job = imapx_is_job_in_queue (
+                       CamelIMAPXJob *job = imapx_server_ref_job (
                                is, select_pending,
                                IMAPX_JOB_REFRESH_INFO, NULL);
                        if (job) {
-                               RefreshInfoData *data = camel_imapx_job_get_data (job);
-
-                               if (data->scan_changes) {
-                                       c (
-                                               is->tagprefix,
-                                               "Will not fetch_new_messages "
-                                               "when already in scan_changes\n");
-                                       goto no_fetch_new;
-                               }
+                               camel_imapx_job_unref (job);
+                               c (
+                                       is->tagprefix,
+                                       "Will not fetch_new_messages when already refreshing information\n");
+                       } else {
+                               imapx_server_fetch_new_messages (is, select_pending, TRUE, TRUE, NULL, NULL);
                        }
-                       imapx_server_fetch_new_messages (
-                               is, select_pending, TRUE, TRUE, NULL, NULL);
-               no_fetch_new:
-                       ;
                }
 
 #if 0  /* see comment for disabled bits in imapx_job_refresh_info_start() */
@@ -6138,7 +6128,6 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
                _("Fetching summary information for new messages in '%s'"),
                camel_folder_get_display_name (folder));
 
-       //printf ("Fetch order: %d/%d\n", fetch_order, CAMEL_SORT_DESCENDING);
        if (diff > uidset_size || fetch_order == CAMEL_SORT_DESCENDING) {
                ic = camel_imapx_command_new (
                        is, "FETCH", mailbox,
@@ -8132,8 +8121,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
 
        QUEUE_LOCK (is);
 
-       job = imapx_is_job_in_queue (
-               is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid);
+       job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid);
 
        if (job != NULL) {
                /* Promote the existing GET_MESSAGE
@@ -8145,6 +8133,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
 
                /* Wait for the job to finish. */
                camel_imapx_job_wait (job, NULL);
+               camel_imapx_job_unref (job);
 
                /* Disregard errors here.  If we failed to retreive the
                 * message from cache (implying the job we were waiting
@@ -8508,11 +8497,11 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is,
        /* Don't run concurrent refreshes on the same mailbox.
         * If a refresh is already in progress, let it finish
         * and return no changes for this refresh request. */
-       job = imapx_is_job_in_queue (
-               is, mailbox, IMAPX_JOB_REFRESH_INFO, NULL);
+       job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_REFRESH_INFO, NULL);
 
        if (job != NULL) {
                QUEUE_UNLOCK (is);
+               camel_imapx_job_unref (job);
                return camel_folder_change_info_new ();
        }
 
@@ -8780,13 +8769,14 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
 
        QUEUE_LOCK (is);
 
-       job = imapx_is_job_in_queue (is, mailbox, IMAPX_JOB_SYNC_CHANGES, NULL);
+       job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_SYNC_CHANGES, NULL);
 
        if (job != NULL) {
                if (pri > job->pri)
                        job->pri = pri;
 
                QUEUE_UNLOCK (is);
+               camel_imapx_job_unref (job);
 
                imapx_sync_free_user (on_user);
                imapx_sync_free_user (off_user);
@@ -8864,10 +8854,11 @@ camel_imapx_server_expunge (CamelIMAPXServer *is,
        /* Do we really care to wait for this one to finish? */
        QUEUE_LOCK (is);
 
-       job = imapx_is_job_in_queue (is, mailbox, IMAPX_JOB_EXPUNGE, NULL);
+       job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_EXPUNGE, NULL);
 
        if (job != NULL) {
                QUEUE_UNLOCK (is);
+               camel_imapx_job_unref (job);
                return TRUE;
        }
 
@@ -9299,6 +9290,52 @@ camel_imapx_server_register_untagged_handler (CamelIMAPXServer *is,
 }
 
 /**
+ * camel_imapx_server_is_job_in_queue:
+ * @imapx_server: a #CamelIMAPXServer instance
+ * @mailbox: a mailbox to search job for
+ * @job_type: a job type specifier to search for
+ * @uid: optional message UID for which the job might be searched
+ *
+ * Searches queue of jobs for the particular job. The returned job
+ * is referenced for thread safety, unref it with camel_imapx_job_unref().
+ *
+ * Returns: %NULL, if such job could not be found, or a referenced job.
+ **/
+CamelIMAPXJob *
+camel_imapx_server_ref_job (CamelIMAPXServer *imapx_server,
+                           CamelIMAPXMailbox *mailbox,
+                           guint32 job_type,
+                           const gchar *uid)
+{
+       GList *head, *link;
+       CamelIMAPXJob *job = NULL;
+       gboolean found = FALSE;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server), NULL);
+
+       QUEUE_LOCK (imapx_server);
+
+       head = g_queue_peek_head_link (&imapx_server->jobs);
+
+       for (link = head; link != NULL; link = g_list_next (link)) {
+               job = (CamelIMAPXJob *) link->data;
+
+               if (!job || !(job->type & job_type))
+                       continue;
+
+               if (camel_imapx_job_matches (job, mailbox, uid)) {
+                       found = TRUE;
+                       camel_imapx_job_ref (job);
+                       break;
+               }
+       }
+
+       QUEUE_UNLOCK (imapx_server);
+
+       return found ? job : NULL;
+}
+
+/**
  * camel_imapx_server_shutdown:
  * @is: a #CamelIMAPXServer
  * @error: a #GError with which cancel any pending jobs
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index ceacc23..4c44db6 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -59,6 +59,7 @@ GQuark                camel_imapx_server_error_quark          (void) G_GNUC_CONST;
 /* Avoid a circular reference. */
 struct _CamelIMAPXStore;
 struct _CamelIMAPXSettings;
+struct _CamelIMAPXJob;
 
 typedef struct _CamelIMAPXServer CamelIMAPXServer;
 typedef struct _CamelIMAPXServerClass CamelIMAPXServerClass;
@@ -267,6 +268,11 @@ const CamelIMAPXUntaggedRespHandlerDesc *
                                                (CamelIMAPXServer *is,
                                                 const gchar *untagged_response,
                                                 const CamelIMAPXUntaggedRespHandlerDesc *desc);
+struct _CamelIMAPXJob *
+               camel_imapx_server_ref_job      (CamelIMAPXServer *imapx_server,
+                                                CamelIMAPXMailbox *mailbox,
+                                                guint32 job_type,
+                                                const gchar *uid);
 
 G_END_DECLS
 
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 6b577d3..803d241 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -39,6 +39,7 @@
 
 #include "camel-imapx-conn-manager.h"
 #include "camel-imapx-folder.h"
+#include "camel-imapx-job.h"
 #include "camel-imapx-server.h"
 #include "camel-imapx-settings.h"
 #include "camel-imapx-store.h"
@@ -3269,3 +3270,32 @@ camel_imapx_store_set_quota_info (CamelIMAPXStore *store,
        g_mutex_unlock (&store->priv->quota_info_lock);
 }
 
+/* Tries to find matching job among all active connections.
+   See camel_imapx_server_ref_job() for more information on parameters
+   and return values.
+*/
+CamelIMAPXJob *
+camel_imapx_store_ref_job (CamelIMAPXStore *imapx_store,
+                          CamelIMAPXMailbox *mailbox,
+                          guint32 job_type,
+                          const gchar *uid)
+{
+       GList *servers, *siter;
+       CamelIMAPXJob *job = NULL;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), NULL);
+
+       servers = camel_imapx_conn_manager_get_connections (imapx_store->priv->con_man);
+
+       for (siter = servers; siter; siter = g_list_next (siter)) {
+               CamelIMAPXServer *imapx_server = siter->data;
+
+               job = camel_imapx_server_ref_job (imapx_server, mailbox, job_type, uid);
+               if (job)
+                       break;
+       }
+
+       g_list_free_full (servers, g_object_unref);
+
+       return job;
+}
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index 2d6f0f4..e927dc3 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -46,6 +46,9 @@
 
 G_BEGIN_DECLS
 
+/* Avoid a circular reference. */
+struct _CamelIMAPXJob;
+
 typedef struct _CamelIMAPXStore CamelIMAPXStore;
 typedef struct _CamelIMAPXStoreClass CamelIMAPXStoreClass;
 typedef struct _CamelIMAPXStorePrivate CamelIMAPXStorePrivate;
@@ -123,6 +126,11 @@ void               camel_imapx_store_set_quota_info
                                                (CamelIMAPXStore *store,
                                                 const gchar *quota_root_name,
                                                 const CamelFolderQuotaInfo *info);
+struct _CamelIMAPXJob *
+               camel_imapx_store_ref_job       (CamelIMAPXStore *imapx_store,
+                                                CamelIMAPXMailbox *mailbox,
+                                                guint32 job_type,
+                                                const gchar *uid);
 
 G_END_DECLS
 


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