summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2016-08-12 17:59:44 +0200
committerMilan Crha <mcrha@redhat.com>2016-08-12 17:59:44 +0200
commit6e44372ce13d49dda74157be734a623e87b77afa (patch)
treec47540d9621694410986b677f0fe0d480e2757a0
parent6c3cff9821913913aac2c8391771f0e978e501a9 (diff)
downloadevolution-data-server-6e44372ce13d49dda74157be734a623e87b77afa.tar.gz
Bug 767564 - Junk check fails due to empty cache file
-rw-r--r--camel/providers/imapx/camel-imapx-mailbox.c53
-rw-r--r--camel/providers/imapx/camel-imapx-mailbox.h2
-rw-r--r--camel/providers/imapx/camel-imapx-server.c51
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 2ea134ff7..054eecd46 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 139b7ee86..9ec86dfb7 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 be72c01e3..1624d214a 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) {