[evolution-data-server] Split new_messages_fetch and scan_changes as separate jobs. Needed for avoiding the duplicate reques



commit 6ba42d5975e5da8adcec38068a7b3ed56e78eb09
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Fri Feb 26 16:22:52 2010 +0530

    Split new_messages_fetch and scan_changes as separate jobs. Needed for avoiding the duplicate requests.
    Add null checks for minfos fetched from folder summary.
    Add null check while operation unref. bug 611166.
    Use a separate uids copy while scanning for changes to be thread-safe.
    Fixes a crash when expunged uid is null.

 camel/providers/imapx/camel-imapx-server.c |  294 ++++++++++++++++------------
 1 files changed, 172 insertions(+), 122 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index bbd03a8..0193e41 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -173,15 +173,16 @@ struct _refresh_info {
 };
 
 enum {
-	IMAPX_JOB_GET_MESSAGE,
-	IMAPX_JOB_APPEND_MESSAGE,
-	IMAPX_JOB_COPY_MESSAGE,
-	IMAPX_JOB_REFRESH_INFO,
-	IMAPX_JOB_SYNC_CHANGES,
-	IMAPX_JOB_EXPUNGE,
-	IMAPX_JOB_NOOP,
-	IMAPX_JOB_IDLE,
-	IMAPX_JOB_LIST,
+	IMAPX_JOB_GET_MESSAGE = 1<<0,
+	IMAPX_JOB_APPEND_MESSAGE = 1<<1,
+	IMAPX_JOB_COPY_MESSAGE = 1<<2,
+	IMAPX_JOB_FETCH_NEW_MESSAGES = 1<<3,
+	IMAPX_JOB_REFRESH_INFO = 1<<4,
+	IMAPX_JOB_SYNC_CHANGES = 1<<5,
+	IMAPX_JOB_EXPUNGE = 1<<6,
+	IMAPX_JOB_NOOP = 1<<7,
+	IMAPX_JOB_IDLE = 1<<8,
+	IMAPX_JOB_LIST = 1<<9,
 };
 
 struct _imapx_flag_change {
@@ -201,7 +202,7 @@ struct _CamelIMAPXJob {
 	//CamelOperation *op;
 
 	gint noreply:1;		/* dont wait for reply */
-	gchar type;		/* operation type */
+	guint32 type;		/* operation type */
 	gchar pri;		/* the command priority */
 	short commands;		/* counts how many commands are outstanding */
 
@@ -952,7 +953,7 @@ found:
 
 /* Must not have QUEUE lock */
 static CamelIMAPXJob *
-imapx_match_active_job (CamelIMAPXServer *is, gint type, const gchar *uid)
+imapx_match_active_job (CamelIMAPXServer *is, guint32 type, const gchar *uid)
 {
 	CamelIMAPXJob *job = NULL;
 	CamelIMAPXCommand *ic;
@@ -961,24 +962,23 @@ imapx_match_active_job (CamelIMAPXServer *is, gint type, const gchar *uid)
 
 	for (ic = (CamelIMAPXCommand *)is->active.head;ic->next;ic=ic->next) {
 		job = ic->job;
-		if (!job || job->type != type)
+		if (!job || !(job->type & type))
 			continue;
 
-		switch (type) {
+		switch (job->type) {
 		case IMAPX_JOB_GET_MESSAGE:
 			if (is->select
 			    && strcmp(job->folder->full_name, is->select) == 0
 			    && strcmp(job->u.get_message.uid, uid) == 0)
 				goto found;
 			break;
+		case IMAPX_JOB_FETCH_NEW_MESSAGES:
 		case IMAPX_JOB_REFRESH_INFO:
+		case IMAPX_JOB_EXPUNGE:
 			if (is->select
 			    && strcmp(job->folder->full_name, is->select) == 0)
 				goto found;
 			break;
-		case IMAPX_JOB_EXPUNGE:
-			if (is->select && strcmp (job->folder->full_name, is->select) == 0)
-				goto found;
 		case IMAPX_JOB_LIST:
 			goto found;
 		}
@@ -1041,10 +1041,13 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
 			gchar *uid = NULL;
 			CamelMessageInfo *mi;
 
+			uid = camel_folder_summary_uid_from_index (imap->select_folder->summary, expunge - 1);
+			if (!uid)
+				break;
+
 			if (imap->changes == NULL)
 				imap->changes = camel_folder_change_info_new();
 
-			uid = camel_folder_summary_uid_from_index (imap->select_folder->summary, expunge - 1);
 			mi = camel_folder_summary_uid (imap->select_folder->summary, uid);
 			if (mi) {
 				imapx_update_summary_for_removed_message (mi, imap->select_folder);
@@ -1175,7 +1178,7 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
 		}
 
 		if ((finfo->got & (FETCH_FLAGS|FETCH_UID)) == (FETCH_FLAGS|FETCH_UID) && !(finfo->got & FETCH_HEADER)) {
-			CamelIMAPXJob *job = imapx_match_active_job(imap, IMAPX_JOB_REFRESH_INFO, NULL);
+			CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
 
 			/* This is either a refresh_info job, check to see if it is and update
 			   if so, otherwise it must've been an unsolicited response, so update
@@ -1196,8 +1199,8 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
 		}
 
 		if ((finfo->got & (FETCH_HEADER|FETCH_UID)) == (FETCH_HEADER|FETCH_UID)) {
-			CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_REFRESH_INFO, NULL);
-
+			CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
+			
 			/* This must be a refresh info job as well, but it has asked for
 			   new messages to be added to the index */
 
@@ -1708,17 +1711,18 @@ camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, CamelExcepti
 }
 
 static void
-imapx_server_fetch_new_messages (CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex)
+imapx_server_fetch_new_messages (CamelIMAPXServer *is, CamelFolder *folder, gboolean async, CamelException *ex)
 {
 	CamelIMAPXJob *job;
 
 	job = g_malloc0(sizeof(*job));
-	job->type = IMAPX_JOB_REFRESH_INFO;
+	job->type = IMAPX_JOB_FETCH_NEW_MESSAGES;
 	job->start = imapx_job_fetch_new_messages_start;
 	job->folder = folder;
-	job->noreply = 1;
+	job->noreply = async;
 	job->ex = ex;
 	job->u.refresh_info.changes = camel_folder_change_info_new();
+	job->op = camel_operation_registered ();
 
 	imapx_run_job (is, job);
 }
@@ -1737,7 +1741,7 @@ idle_thread (gpointer data)
 
 		if (!camel_exception_is_set (ex) && ifolder->exists_on_server >
 				camel_folder_summary_count (((CamelFolder *) ifolder)->summary) && imapx_is_command_queue_empty (is))
-			imapx_server_fetch_new_messages (is, is->select_folder, ex);
+			imapx_server_fetch_new_messages (is, is->select_folder, TRUE, ex);
 
 		if (camel_exception_is_set (ex)) {
 			printf ("Caught exception in idle thread:  %s \n", ex->desc);
@@ -2489,12 +2493,12 @@ imapx_job_append_message_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static gint
-imapx_refresh_info_uid_cmp(gconstpointer ap, gconstpointer bp)
+imapx_refresh_info_uid_cmp (gconstpointer ap, gconstpointer bp)
 {
 	guint av, bv;
 
-	av = strtoul((const gchar *)ap, NULL, 10);
-	bv = strtoul((const gchar *)bp, NULL, 10);
+	av = g_ascii_strtoull ((const gchar *)ap, NULL, 10);
+	bv = g_ascii_strtoull ((const gchar *)bp, NULL, 10);
 
 	if (av<bv)
 		return -1;
@@ -2505,34 +2509,46 @@ imapx_refresh_info_uid_cmp(gconstpointer ap, gconstpointer bp)
 }
 
 static gint
-imapx_refresh_info_cmp(gconstpointer ap, gconstpointer bp)
+imapx_uids_array_cmp (gconstpointer ap, gconstpointer bp)
+{
+	const gchar **a = (const gchar **) ap;
+        const gchar **b = (const gchar **) bp;
+
+	return imapx_refresh_info_uid_cmp (*a, *b);
+}
+
+static gint
+imapx_refresh_info_cmp (gconstpointer ap, gconstpointer bp)
 {
 	const struct _refresh_info *a = ap;
 	const struct _refresh_info *b = bp;
 
-	return imapx_refresh_info_uid_cmp(a->uid, b->uid);
+	return imapx_refresh_info_uid_cmp (a->uid, b->uid);
 }
 
 /* skips over non-server uids (pending appends) */
 static guint
-imapx_index_next (CamelFolderSummary *s, guint index)
+imapx_index_next (GPtrArray *uids, CamelFolderSummary *s, guint index)
 {
-	guint count = 0;
 
-	count = camel_folder_summary_count (s);
-
-	while (index < count) {
-		const CamelMessageInfo *info;
+	while (index < uids->len) {
+		CamelMessageInfo *info;
 
 		index++;
-		info = camel_folder_summary_index (s, index);
+		if(index >= uids->len)
+			break;
+
+		info = camel_folder_summary_uid (s, g_ptr_array_index (uids, index));
 		if (!info)
 			continue;
 
 		if (info && (strchr(camel_message_info_uid(info), '-') != NULL)) {
+			camel_message_info_free (info);
 			printf("Ignoring offline uid '%s'\n", camel_message_info_uid(info));
-		} else
+		} else {
+			camel_message_info_free (info);
 			break;
+		}
 	}
 
 	return index;
@@ -2632,7 +2648,7 @@ imapx_uid_cmp(gconstpointer ap, gconstpointer bp, gpointer data)
 }
 
 static void
-imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_job_scan_changes_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
 	gint i;
@@ -2646,7 +2662,8 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		GSList *removed = NULL, *l;
 		gboolean fetch_new = FALSE;
 		gint i;
-		guint j = 0, total = 0;
+		guint j = 0;
+		GPtrArray *uids;
 
 		/* Here we do the typical sort/iterate/merge loop.
 		   If the server flags dont match what we had, we modify our
@@ -2657,27 +2674,35 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		   anything missing in our summary, and also queue up jobs
 		   for all outstanding messages to be uploaded */
 
+		/* obtain a copy to be thread safe */
+		uids = camel_folder_summary_array (s);
+
 		qsort(infos->data, infos->len, sizeof(struct _refresh_info), imapx_refresh_info_cmp);
-		total = camel_folder_summary_count (s);
-		s_minfo = camel_folder_summary_index (s, 0);
+		g_ptr_array_sort(uids, (GCompareFunc) imapx_uids_array_cmp);
+
+		if (uids->len)
+			s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, 0));
 
 		for (i=0; i<infos->len; i++) {
 			struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
 
-			while (s_minfo && uid_cmp(camel_message_info_uid(s_minfo), r->uid, s) < 0) {
+			while (s_minfo && uid_cmp (camel_message_info_uid(s_minfo), r->uid, s) < 0) {
 				const gchar *uid = camel_message_info_uid (s_minfo);
 
 				camel_folder_change_info_remove_uid (job->u.refresh_info.changes, uid);
 				removed = g_slist_prepend (removed, (gpointer ) g_strdup (uid));
 				camel_message_info_free (s_minfo);
+				s_minfo = NULL;
 				
-				j = imapx_index_next (s, j);
-				s_minfo = camel_folder_summary_index (s, j);
+				j = imapx_index_next (uids, s, j);
+				if (j < uids->len)
+					s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
 			}
 
 			info = NULL;
 			if (s_minfo && uid_cmp(s_minfo->uid, r->uid, s) == 0) {
 				info = (CamelIMAPXMessageInfo *)s_minfo;
+				g_message ("same UID  %s \n", s_minfo->uid);
 
 				if (imapx_update_message_info_flags ((CamelMessageInfo *) info, r->server_flags, r->server_user_flags, job->folder))
 					camel_folder_change_info_change_uid (job->u.refresh_info.changes, camel_message_info_uid (s_minfo));
@@ -2685,21 +2710,24 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 			} else
 				fetch_new = TRUE;
 
-			if (s_minfo)
+			if (s_minfo) {
 				camel_message_info_free (s_minfo);
+				s_minfo = NULL;
+			}
 			
-			if (j > total)
+			if (j >= uids->len)
 				break;
 
-			j = imapx_index_next (s, j);
-			s_minfo = camel_folder_summary_index (s, j);
+			j = imapx_index_next (uids, s, j);
+			if (j < uids->len)
+				s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
 		}
 
 		if (s_minfo)
 			camel_message_info_free (s_minfo);
 
-		while (j < total) {
-			s_minfo = camel_folder_summary_index (s, j);
+		while (j < uids->len) {
+			s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
 
 			if (!s_minfo) {
 				j++;
@@ -2738,6 +2766,8 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 			camel_object_trigger_event(job->folder, "folder_changed", job->u.refresh_info.changes);
 		camel_folder_change_info_clear(job->u.refresh_info.changes);
 
+		camel_folder_free_uids (job->folder, uids);
+
 		/* If we have any new messages, download their headers, but only a few (100?) at a time */
 		if (fetch_new) {
 			camel_operation_start (job->op, _("Fetching summary information for new messages in %s"), job->folder->name);
@@ -2766,7 +2796,7 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_refresh_info_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_scan_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
@@ -2775,7 +2805,7 @@ imapx_job_refresh_info_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 	ic = camel_imapx_command_new ("FETCH", job->folder->full_name,
 				     "FETCH 1:* (UID FLAGS)");
 	ic->job = job;
-	ic->complete = imapx_job_refresh_info_done;
+	ic->complete = imapx_job_scan_changes_done;
 	job->u.refresh_info.infos = g_array_new (0, 0, sizeof(struct _refresh_info));
 	imapx_command_queue (is, ic);
 }
@@ -2795,15 +2825,16 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *
 		imapx_update_store_summary (ic->job->folder);
 		camel_folder_summary_save_to_db (ic->job->folder->summary, NULL);
 		camel_object_trigger_event(ic->job->folder, "folder_changed", ic->job->u.refresh_info.changes);
+		camel_folder_change_info_clear(ic->job->u.refresh_info.changes);
 	}
 
 
 exception:
-	camel_operation_end (ic->job->op);
-	
 	if (ic->job->noreply)
 		camel_folder_change_info_free(ic->job->u.refresh_info.changes);
 
+	if (ic->job->op)
+		camel_operation_unref (ic->job->op);
 	imapx_job_done (is, ic->job);
 	camel_imapx_command_free (ic);
 }
@@ -2844,6 +2875,72 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 	imapx_command_queue (is, ic);
 }
 
+static void
+imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+{
+	guint32 total;
+	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder;
+	CamelFolder *folder = job->folder;
+	CamelException *ex = job->ex;
+	
+	total = camel_folder_summary_count (folder->summary);
+	/* Check if there are any new messages. The old imap doc says one needs to reselect in case of inbox to fetch
+	   new messages. Need to check if its still true. Just use noop now */
+	if (ifolder->exists_on_server == total) {
+		camel_imapx_server_noop (is, folder, ex);
+
+		if (camel_exception_is_set (ex))
+			goto exception;
+	}
+
+	/* Fetch the new messages */
+	if (ifolder->exists_on_server > total || total == 0)
+	{
+		imapx_server_fetch_new_messages (is, folder, FALSE, job->ex);
+		if (camel_exception_is_set (job->ex))
+			goto exception;
+	}
+
+	/* Sync changes before fetching status, else unread count will not match. need to think about better ways for this */
+	camel_imapx_server_sync_changes (is, folder, ex);
+	if (camel_exception_is_set (job->ex))
+		goto exception;
+
+	/* Check if a rescan is needed */
+	total = camel_folder_summary_count (folder->summary);
+	if (ifolder->exists_on_server == total) {
+		guint32 unread;
+		CamelIMAPXCommand *ic;
+
+		ic = camel_imapx_command_new ("STATUS", folder->full_name, "STATUS %s (MESSAGES UNSEEN)", folder->full_name);
+		ic->job = job;
+		ic->complete = imapx_command_status_done;
+		imapx_command_run_sync (is, ic);
+
+		if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
+			if (!camel_exception_is_set (ic->ex))
+				camel_exception_setv(job->ex, 1, "Error refreshing folder: %s", ic->status->text);
+			else
+				camel_exception_xfer (job->ex, ic->ex);
+
+			camel_imapx_command_free (ic);
+			goto exception;
+		}
+		camel_imapx_command_free (ic);
+
+		camel_object_get (folder, NULL, CAMEL_FOLDER_UNREAD, &unread, NULL);
+		if (ifolder->exists_on_server == total && unread == ifolder->unread_on_server)
+			goto exception;
+	}
+
+	imapx_job_scan_changes_start (is, job);
+	return;
+
+exception:
+	imapx_job_done (is, job);
+}
+
+
 /* ********************************************************************** */
 
 static void
@@ -3027,6 +3124,9 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 			CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (job->folder->summary,
 					job->u.sync_changes.changed_uids->pdata[i]);
 
+			if (!info)
+				continue;
+			
 			info->server_flags = ((CamelMessageInfoBase *)info)->flags & CAMEL_IMAPX_SERVER_FLAGS;
 			info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
 			info->info.dirty = TRUE;
@@ -3087,10 +3187,16 @@ imapx_job_sync_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 			for (i = 0; i < uids->len; i++) {
 				CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *)camel_folder_summary_uid
 										(job->folder->summary, uids->pdata[i]);
+				guint32 flags;
+				guint32 sflags;
+				gint send;
 
-				guint32 flags = ((CamelMessageInfoBase *)info)->flags & CAMEL_IMAPX_SERVER_FLAGS;
-				guint32 sflags = info->server_flags & CAMEL_IMAPX_SERVER_FLAGS;
-				gint send = 0;
+				if (!info)
+					continue;
+				
+				flags = ((CamelMessageInfoBase *)info)->flags & CAMEL_IMAPX_SERVER_FLAGS;
+				sflags = info->server_flags & CAMEL_IMAPX_SERVER_FLAGS;
+				send = 0;
 
 				if ( (on && (((flags ^ sflags) & flags) & flag))
 				     || (!on && (((flags ^ sflags) & ~flags) & flag))) {
@@ -3581,7 +3687,8 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar
 	imapx_run_job(is, job);
 
 	stream = job->u.get_message.stream;
-	camel_operation_unref (job->op);
+	if (job->op)
+		camel_operation_unref (job->op);
 	g_free(job);
 
 	if (stream) {
@@ -3772,84 +3879,24 @@ void
 camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex)
 {
 	CamelIMAPXJob *job;
-	guint32 total;
-	CamelIMAPXCommand *ic;
-	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
 
 	job = g_malloc0(sizeof(*job));
 	job->type = IMAPX_JOB_REFRESH_INFO;
-	job->start = imapx_job_fetch_new_messages_start;
+	job->start = imapx_job_refresh_info_start;
 	job->folder = folder;
 	job->ex = ex;
 	job->op = camel_operation_registered ();
 	job->u.refresh_info.changes = camel_folder_change_info_new();
 
-	total = camel_folder_summary_count (folder->summary);
-
-	/* Check if there are any new messages. The old imap doc says one needs to reselect in case of inbox to fetch
-	    new messages. Need to check if its still true. Just use noop now */
-	if (ifolder->exists_on_server == total) {
-		camel_imapx_server_noop (is, folder, ex);
-
-		if (camel_exception_is_set (ex))
-			goto done;
-	}
-
-	/* Fetch the new messages */
-	if (ifolder->exists_on_server > total)
-	{
-		imapx_run_job(is, job);
-
-		if (camel_folder_change_info_changed(job->u.refresh_info.changes))
-			camel_object_trigger_event(folder, "folder_changed", job->u.refresh_info.changes);
-		camel_folder_change_info_clear(job->u.refresh_info.changes);
-
-		if (camel_exception_is_set (job->ex))
-			goto done;
-	}
-
-	/* Sync changes before fetching status, else unread count will not match. need to think about better ways for this */
-	camel_imapx_server_sync_changes (is, folder, ex);
-	if (camel_exception_is_set (job->ex))
-		goto done;
-
-	total = camel_folder_summary_count (folder->summary);
-
-	/* Check if a rescan is needed */
-	if (ifolder->exists_on_server == total) {
-		guint32 unread;
-
-		ic = camel_imapx_command_new ("STATUS", folder->full_name, "STATUS %s (MESSAGES UNSEEN)", folder->full_name);
-		ic->job = job;
-		ic->complete = imapx_command_status_done;
-		imapx_command_run_sync (is, ic);
-
-		if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
-			if (!camel_exception_is_set (ic->ex))
-				camel_exception_setv(job->ex, 1, "Error refreshing folder: %s", ic->status->text);
-			else
-				camel_exception_xfer (job->ex, ic->ex);
-
-			camel_imapx_command_free (ic);
-			goto done;
-		}
-		camel_imapx_command_free (ic);
-
-		camel_object_get (folder, NULL, CAMEL_FOLDER_UNREAD, &unread, NULL);
-		if (ifolder->exists_on_server == total && unread == ifolder->unread_on_server)
-			goto done;
-	}
-
-	/* sync all the changed messages */
-	job->start = imapx_job_refresh_info_start;
 	imapx_run_job (is, job);
 
 	if (camel_folder_change_info_changed(job->u.refresh_info.changes))
 		camel_object_trigger_event(folder, "folder_changed", job->u.refresh_info.changes);
 
-done:
 	camel_folder_change_info_free(job->u.refresh_info.changes);
-	camel_operation_unref (job->op);
+	
+	if (job->op)
+		camel_operation_unref (job->op);
 	g_free(job);
 }
 
@@ -3909,6 +3956,9 @@ camel_imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, Camel
 
 		info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (folder->summary, uids->pdata[i]);
 
+		if (!info)
+			continue;
+
 		if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
 			camel_message_info_free (info);
 			continue;



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