[evolution-data-server/gnome-2-30] imapx: Avoid running FETCH_NEW_MESSAGES and REFRESH_INFO jobs simultaneously



commit 407df6e929f9abacf625b57ddd35fb0142ac563b
Author: David Woodhouse <David Woodhouse intel com>
Date:   Sun Jul 11 15:11:17 2010 +0100

    imapx: Avoid running FETCH_NEW_MESSAGES and REFRESH_INFO jobs simultaneously
    
    There are various places where we interpret FETCH results and use
    imapx_match_active_job to find the current job, which will behave badly
    if there are two jobs which could potentially be responsible for the FETCH.
    
    In particular, this was causing a problem when we triggered a fetch of new
    messages from select_done(), and that command was submitted at the same time
    as a refresh_info command to fetch all flags. The server (Dovecot) was
    returning all the untagged FETCH results before either completion line,
    and all the flags were getting "assigned" to the fetch_new_messages job,
    causing a bunch of 'g_array_append_vals: assertion `array' failed' warnings,
    and all messages to disappear because the refresh_info job didn't see them.
    (cherry picked from commit 1d1b146e58f918f67ccff93c4fb5388429bf12e7)

 camel/providers/imapx/camel-imapx-server.c |   22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 519ea86..4a6746e 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -310,6 +310,7 @@ struct _CamelIMAPXJob {
 	} u;
 };
 
+static CamelIMAPXJob *imapx_match_active_job (CamelIMAPXServer *is, guint32 type, const gchar *uid);
 static void imapx_job_done (CamelIMAPXServer *is, CamelIMAPXJob *job);
 static void imapx_run_job (CamelIMAPXServer *is, CamelIMAPXJob *job);
 static void imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job);
@@ -846,6 +847,21 @@ imapx_command_start (CamelIMAPXServer *imap, CamelIMAPXCommand *ic)
 	return TRUE;
 }
 
+static gboolean duplicate_fetch_or_refresh(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+{
+	if (!ic->job)
+		return FALSE;
+
+	if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO)))
+		return FALSE;
+
+	if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL)) {
+		c(printf("Not yet sending duplicate fetch/refresh %s command\n", ic->name));
+		return TRUE;
+	}
+
+	return FALSE;
+}
 /* See if we can start another task yet.
 
 	If we're waiting for a literal, we cannot proceed.
@@ -947,7 +963,8 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex)
 		nc = ic->next;
 		while (nc && is->literal == NULL && count < MAX_COMMANDS && ic->pri >= pri) {
 			c(printf("-- %3d '%s'?\n", (gint)ic->pri, ic->name));
-			if (!ic->select || (ic->select == is->select_folder)) {
+			if (!ic->select || ((ic->select == is->select_folder) &&
+					    !duplicate_fetch_or_refresh(is, ic))) {
 				c(printf("--> starting '%s'\n", ic->name));
 				pri = ic->pri;
 				camel_dlist_remove((CamelDListNode *)ic);
@@ -980,7 +997,8 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex)
 		nc = ic->next;
 		count = 0;
 		while (nc && is->literal == NULL && count < MAX_COMMANDS && ic->pri >= pri) {
-			if (!ic->select || ic->select == is->select_folder) {
+			if (!ic->select || (ic->select == is->select_folder &&
+					    !duplicate_fetch_or_refresh(is, ic))) {
 				c(printf("* queueing job %3d '%s'\n", (gint)ic->pri, ic->name));
 				pri = ic->pri;
 				camel_dlist_remove((CamelDListNode *)ic);



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