[evolution-data-server] Bug 767564 - Junk check fails due to empty cache file



commit 6e44372ce13d49dda74157be734a623e87b77afa
Author: Milan Crha <mcrha redhat com>
Date:   Fri Aug 12 17:59:44 2016 +0200

    Bug 767564 - Junk check fails due to empty cache file

 camel/providers/imapx/camel-imapx-mailbox.c |   53 ++++++++++++++++++++++++---
 camel/providers/imapx/camel-imapx-mailbox.h |    2 +
 camel/providers/imapx/camel-imapx-server.c  |   51 +++++++++++++++++++++++++-
 3 files changed, 98 insertions(+), 8 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-mailbox.c b/camel/providers/imapx/camel-imapx-mailbox.c
index 2ea134f..054eecd 100644
--- a/camel/providers/imapx/camel-imapx-mailbox.c
+++ b/camel/providers/imapx/camel-imapx-mailbox.c
@@ -48,6 +48,8 @@ struct _CamelIMAPXMailboxPrivate {
        guint64 highestmodseq;
        guint32 permanentflags;
 
+       volatile gint change_stamp;
+
        CamelIMAPXMailboxState state;
 
        GMutex property_lock;
@@ -131,6 +133,7 @@ camel_imapx_mailbox_init (CamelIMAPXMailbox *mailbox)
        mailbox->priv->permanentflags = ~0;
        mailbox->priv->state = CAMEL_IMAPX_MAILBOX_STATE_CREATED;
        mailbox->priv->update_count = 0;
+       mailbox->priv->change_stamp = 0;
 }
 
 /**
@@ -494,7 +497,12 @@ camel_imapx_mailbox_set_messages (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->messages == messages)
+               return;
+
        mailbox->priv->messages = messages;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -536,7 +544,12 @@ camel_imapx_mailbox_set_recent (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->recent == recent)
+               return;
+
        mailbox->priv->recent = recent;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -580,7 +593,12 @@ camel_imapx_mailbox_set_unseen (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->unseen == unseen)
+               return;
+
        mailbox->priv->unseen = unseen;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -622,7 +640,12 @@ camel_imapx_mailbox_set_uidnext (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->uidnext == uidnext)
+               return;
+
        mailbox->priv->uidnext = uidnext;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -664,7 +687,12 @@ camel_imapx_mailbox_set_uidvalidity (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->uidvalidity == uidvalidity)
+               return;
+
        mailbox->priv->uidvalidity = uidvalidity;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -710,7 +738,12 @@ camel_imapx_mailbox_set_highestmodseq (CamelIMAPXMailbox *mailbox,
 {
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
+       if (mailbox->priv->highestmodseq == highestmodseq)
+               return;
+
        mailbox->priv->highestmodseq = highestmodseq;
+
+       g_atomic_int_add (&mailbox->priv->change_stamp, 1);
 }
 
 /**
@@ -1181,22 +1214,22 @@ camel_imapx_mailbox_handle_status_response (CamelIMAPXMailbox *mailbox,
        g_return_if_fail (CAMEL_IS_IMAPX_STATUS_RESPONSE (response));
 
        if (camel_imapx_status_response_get_messages (response, &value32))
-               mailbox->priv->messages = value32;
+               camel_imapx_mailbox_set_messages (mailbox, value32);
 
        if (camel_imapx_status_response_get_recent (response, &value32))
-               mailbox->priv->recent = value32;
+               camel_imapx_mailbox_set_recent (mailbox, value32);
 
        if (camel_imapx_status_response_get_unseen (response, &value32))
-               mailbox->priv->unseen = value32;
+               camel_imapx_mailbox_set_unseen (mailbox, value32);
 
        if (camel_imapx_status_response_get_uidnext (response, &value32))
-               mailbox->priv->uidnext = value32;
+               camel_imapx_mailbox_set_uidnext (mailbox, value32);
 
        if (camel_imapx_status_response_get_uidvalidity (response, &value32))
-               mailbox->priv->uidvalidity = value32;
+               camel_imapx_mailbox_set_uidvalidity (mailbox, value32);
 
        if (camel_imapx_status_response_get_highestmodseq (response, &value64))
-               mailbox->priv->highestmodseq = value64;
+               camel_imapx_mailbox_set_highestmodseq (mailbox, value64);
 }
 
 gint
@@ -1219,3 +1252,11 @@ camel_imapx_mailbox_inc_update_count (CamelIMAPXMailbox *mailbox,
        mailbox->priv->update_count += inc;
        g_mutex_unlock (&mailbox->priv->update_lock);
 }
+
+gint
+camel_imapx_mailbox_get_change_stamp (CamelIMAPXMailbox *mailbox)
+{
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), 0);
+
+       return mailbox->priv->change_stamp;
+}
diff --git a/camel/providers/imapx/camel-imapx-mailbox.h b/camel/providers/imapx/camel-imapx-mailbox.h
index 139b7ee..9ec86df 100644
--- a/camel/providers/imapx/camel-imapx-mailbox.h
+++ b/camel/providers/imapx/camel-imapx-mailbox.h
@@ -180,6 +180,8 @@ gint                camel_imapx_mailbox_get_update_count
 void           camel_imapx_mailbox_inc_update_count
                                        (CamelIMAPXMailbox *mailbox,
                                         gint inc);
+gint           camel_imapx_mailbox_get_change_stamp
+                                       (CamelIMAPXMailbox *mailbox);
 
 G_END_DECLS
 
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index be72c01..1624d21 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -255,6 +255,7 @@ struct _CamelIMAPXServerPrivate {
        GMutex select_lock;
        GWeakRef select_mailbox;
        GWeakRef select_pending;
+       gint last_selected_mailbox_change_stamp;
 
        GMutex changes_lock;
        CamelFolderChangeInfo *changes;
@@ -1792,9 +1793,15 @@ imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
                        select_mailbox = g_weak_ref_get (&is->priv->select_mailbox);
                        select_pending = g_weak_ref_get (&is->priv->select_pending);
 
-                       if (select_mailbox == NULL)
+                       if (select_mailbox == NULL) {
                                g_weak_ref_set (&is->priv->select_mailbox, select_pending);
 
+                               if (select_pending)
+                                       is->priv->last_selected_mailbox_change_stamp = 
camel_imapx_mailbox_get_change_stamp (select_pending);
+                               else
+                                       is->priv->last_selected_mailbox_change_stamp = 0;
+                       }
+
                        g_mutex_unlock (&is->priv->select_lock);
 
                        g_clear_object (&select_mailbox);
@@ -3660,8 +3667,24 @@ camel_imapx_server_ensure_selected_sync (CamelIMAPXServer *is,
        g_mutex_lock (&is->priv->select_lock);
        selected_mailbox = g_weak_ref_get (&is->priv->select_mailbox);
        if (selected_mailbox == mailbox) {
+               gboolean request_noop;
+               gint change_stamp;
+
+               change_stamp = selected_mailbox ? camel_imapx_mailbox_get_change_stamp (selected_mailbox) : 0;
+               request_noop = selected_mailbox && is->priv->last_selected_mailbox_change_stamp != 
change_stamp;
+
+               if (request_noop)
+                       is->priv->last_selected_mailbox_change_stamp = change_stamp;
+
                g_mutex_unlock (&is->priv->select_lock);
                g_clear_object (&selected_mailbox);
+
+               if (request_noop) {
+                       c (is->priv->tagprefix, "%s: Selected mailbox '%s' changed, do NOOP instead\n", 
G_STRFUNC, camel_imapx_mailbox_get_name (mailbox));
+
+                       return camel_imapx_server_noop_sync (is, mailbox, cancellable, error);
+               }
+
                return TRUE;
        }
 
@@ -3690,9 +3713,11 @@ camel_imapx_server_ensure_selected_sync (CamelIMAPXServer *is,
 
        if (success) {
                is->priv->state = IMAPX_SELECTED;
+               is->priv->last_selected_mailbox_change_stamp = camel_imapx_mailbox_get_change_stamp (mailbox);
                g_weak_ref_set (&is->priv->select_mailbox, mailbox);
        } else {
                is->priv->state = IMAPX_INITIALISED;
+               is->priv->last_selected_mailbox_change_stamp = 0;
                g_weak_ref_set (&is->priv->select_mailbox, NULL);
        }
 
@@ -3910,6 +3935,7 @@ imapx_disconnect (CamelIMAPXServer *is)
        g_mutex_unlock (&is->priv->stream_lock);
 
        g_mutex_lock (&is->priv->select_lock);
+       is->priv->last_selected_mailbox_change_stamp = 0;
        g_weak_ref_set (&is->priv->select_mailbox, NULL);
        g_weak_ref_set (&is->priv->select_pending, NULL);
        g_mutex_unlock (&is->priv->select_lock);
@@ -4027,7 +4053,7 @@ camel_imapx_server_get_message_sync (CamelIMAPXServer *is,
        GIOStream *cache_stream;
        gsize data_size;
        gboolean use_multi_fetch;
-       gboolean success;
+       gboolean success, retrying = FALSE;
        GError *local_error = NULL;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), NULL);
@@ -4069,6 +4095,7 @@ camel_imapx_server_get_message_sync (CamelIMAPXServer *is,
 
        is->priv->get_message_stream = cache_stream;
 
+ try_again:
        if (use_multi_fetch) {
                CamelIMAPXCommand *ic;
                gsize fetch_offset = 0;
@@ -4111,6 +4138,26 @@ camel_imapx_server_get_message_sync (CamelIMAPXServer *is,
                camel_imapx_command_unref (ic);
        }
 
+       if (success && !retrying && !g_seekable_tell (G_SEEKABLE (is->priv->get_message_stream))) {
+               /* Nothing had been read from the server. Maybe this connection
+                  doesn't know about the message on the server side yet, thus
+                  invoke NOOP and retry. */
+               CamelIMAPXCommand *ic;
+
+               retrying = TRUE;
+
+               c (is->priv->tagprefix, "%s: Returned no message data, retrying after NOOP\n", G_STRFUNC);
+
+               ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_NOOP, "NOOP");
+
+               success = camel_imapx_server_process_command_sync (is, ic, _("Error performing NOOP"), 
cancellable, &local_error);
+
+               camel_imapx_command_unref (ic);
+
+               if (success)
+                       goto try_again;
+       }
+
        is->priv->get_message_stream = NULL;
 
        if (success) {


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