[evolution-ews] Bug #686227 - Calendar does repeated ResolveNames requests for the same people



commit 39da2c5742458c75aebd9831dc5b9a3ac0b9c5a5
Author: Milan Crha <mcrha redhat com>
Date:   Fri Nov 9 15:37:16 2012 +0100

    Bug #686227 - Calendar does repeated ResolveNames requests for the same people

 src/addressbook/e-book-backend-ews.c |   12 +-
 src/calendar/e-cal-backend-ews.c     |  564 +++++++++++-----------------------
 src/camel/camel-ews-folder.c         |    5 +-
 src/server/e-ews-connection.c        |   21 +-
 src/server/e-ews-connection.h        |    9 +-
 5 files changed, 215 insertions(+), 396 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 39f3e25..e26ff5e 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -2314,15 +2314,21 @@ ebews_start_sync (gpointer data)
 	{
 		GSList *items_created = NULL, *items_updated = NULL;
 		GSList *items_deleted = NULL;
+		gchar *old_sync_state = sync_state;
+
+		sync_state = NULL;
 
 		e_ews_connection_sync_folder_items_sync (
 			priv->cnc, EWS_PRIORITY_MEDIUM,
-			&sync_state, priv->folder_id,
-			"IdOnly", NULL,
-			EWS_MAX_FETCH_COUNT, &includes_last_item,
+			old_sync_state, priv->folder_id,
+			"IdOnly", NULL, EWS_MAX_FETCH_COUNT,
+			&sync_state,
+			&includes_last_item,
 			&items_created, &items_updated,
 			&items_deleted, priv->cancellable, &error);
 
+		g_free (old_sync_state);
+
 		if (error)
 			break;
 
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index fc85b52..15531ac 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -63,8 +63,6 @@
 #define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
 #endif
 
-typedef struct _SyncItemsClosure SyncItemsClosure;
-
 /* Private part of the CalBackendEws structure */
 struct _ECalBackendEwsPrivate {
 	/* Fields required for online server requests */
@@ -87,16 +85,6 @@ struct _ECalBackendEwsPrivate {
 	GCancellable *cancellable;
 };
 
-struct _SyncItemsClosure {
-	ECalBackendEws *backend;
-	EEwsConnection *connection;
-	gchar *sync_state;
-	gboolean includes_last_item;
-	GSList *items_created;
-	GSList *items_deleted;
-	GSList *items_updated;
-};
-
 #define PRIV_LOCK(p)   (g_rec_mutex_lock (&(p)->rec_mutex))
 #define PRIV_UNLOCK(p) (g_rec_mutex_unlock (&(p)->rec_mutex))
 
@@ -122,7 +110,6 @@ struct _SyncItemsClosure {
 		}								\
 	} G_STMT_END
 
-static void ews_cal_sync_items_ready_cb (GObject *obj, GAsyncResult *res, gpointer user_data);
 static void ews_cal_component_get_item_id (ECalComponent *comp, gchar **itemid, gchar **changekey);
 static gboolean ews_start_sync	(gpointer data);
 static icaltimezone * e_cal_get_timezone_from_ical_component (ECalBackend *backend, icalcomponent *comp);
@@ -139,28 +126,6 @@ G_DEFINE_TYPE_WITH_CODE (
 		E_TYPE_SOURCE_AUTHENTICATOR,
 		e_cal_backend_ews_authenticator_init))
 
-static void
-sync_items_closure_free (SyncItemsClosure *closure)
-{
-	g_object_unref (closure->backend);
-	g_object_unref (closure->connection);
-	g_free (closure->sync_state);
-
-	g_slist_free_full (
-		closure->items_created,
-		(GDestroyNotify) g_object_unref);
-
-	g_slist_free_full (
-		closure->items_updated,
-		(GDestroyNotify) g_object_unref);
-
-	g_slist_free_full (
-		closure->items_deleted,
-		(GDestroyNotify) g_free);
-
-	g_slice_free (SyncItemsClosure, closure);
-}
-
 static CamelEwsSettings *
 cal_backend_ews_get_collection_settings (ECalBackendEws *backend)
 {
@@ -2848,126 +2813,82 @@ put_component_to_store (ECalBackendEws *cbews,
 	e_cal_backend_store_put_component_with_time_range (priv->store, comp, time_start, time_end);
 }
 
-typedef struct {
-	ECalBackendEws *cbews;
-	gchar *itemid;
-} EwsAttachmentData;
-
 static void
-ews_get_attachments_ready_callback (GObject *object,
-                                    GAsyncResult *res,
-                                    gpointer user_data)
+ews_get_attachments (ECalBackendEws *cbews,
+                     EEwsItem *item)
 {
-	EEwsConnection *cnc = E_EWS_CONNECTION (object);
-	EwsAttachmentData *att_data = user_data;
-	GError *error = NULL;
-	GSList *uris = NULL, *ids, *i;
-	ECalComponentId *id;
-	ECalBackendEws *cbews;
-	gchar *itemid;
-	ECalComponent *comp_att, *cache_comp = NULL;
-	icalcomponent *icalcomp;
-	icalproperty *icalprop;
-	icalparameter *icalparam;
-
-	ids = e_ews_connection_get_attachments_finish (cnc, res, &uris, &error);
+	gboolean has_attachment = FALSE;
+	const GSList *attachment_ids, *aid;
+	const EwsId *item_id;
+	ECalComponent *comp;
+	const gchar *uid;
+	GSList *uris = NULL;
 
-	cbews = att_data->cbews;
-	itemid = att_data->itemid;
+	e_ews_item_has_attachments (item, &has_attachment);
+	if (!has_attachment)
+		return;
 
-	if (error)
-		goto exit;
+	item_id = e_ews_item_get_id (item);
+	g_return_if_fail (item_id != NULL);
 
 	PRIV_LOCK (cbews->priv);
-	comp_att = g_hash_table_lookup (cbews->priv->item_id_hash, itemid);
-	if (!comp_att) {
+	comp = g_hash_table_lookup (cbews->priv->item_id_hash, item_id->id);
+	if (!comp) {
 		PRIV_UNLOCK (cbews->priv);
-		goto exit;
-	}
-	PRIV_UNLOCK (cbews->priv);
-
-	e_cal_component_set_attachment_list (comp_att, uris);
-
-	icalcomp = e_cal_component_get_icalcomponent (comp_att);
-	icalprop = icalcomponent_get_first_property (icalcomp, ICAL_ATTACH_PROPERTY);
-	i = ids;
-	for (; i && icalprop; i = i->next, icalprop = icalcomponent_get_next_property (icalcomp, ICAL_ATTACH_PROPERTY)) {
-		icalparam = icalparameter_new_x (i->data);
-		icalparameter_set_xname (icalparam, "X-EWS-ATTACHMENTID");
-		icalproperty_add_parameter (icalprop, icalparam);
-		g_free (i->data);
+		g_warning ("%s: Failed to get component from item_id_hash", G_STRFUNC);
+		return;
 	}
 
-	id = e_cal_component_get_id (comp_att);
-	cache_comp = e_cal_backend_store_get_component (cbews->priv->store, id->uid, id->rid);
-	e_cal_component_free_id (id);
+	e_cal_component_get_uid (comp, &uid);
 
-	put_component_to_store (cbews, comp_att);
+	attachment_ids = e_ews_item_get_attachments_ids (item);
 
-	if (cache_comp)
-		e_cal_backend_notify_component_modified (E_CAL_BACKEND (cbews), cache_comp, comp_att);
+	if (e_ews_connection_get_attachments_sync (
+		cbews->priv->cnc,
+		EWS_PRIORITY_MEDIUM,
+		uid,
+		attachment_ids,
+		cbews->priv->storage_path,
+		TRUE,
+		&uris,
+		NULL, NULL,
+		cbews->priv->cancellable,
+		NULL)) {
+		icalcomponent *icalcomp;
+		icalproperty *icalprop;
+		icalparameter *icalparam;
+		ECalComponentId *id;
+		ECalComponent *cache_comp;
 
- exit:
-	g_clear_error (&error);
-	g_slist_free_full (uris, g_free);
-	g_object_unref (att_data->cbews);
-	g_free (att_data->itemid);
-	g_free (att_data);
-}
+		e_cal_component_set_attachment_list (comp, uris);
 
-static void
-ews_get_attachments (ECalBackendEws *cbews,
-                     EEwsItem *item)
-{
-	gboolean has_attachment = FALSE;
-
-	e_ews_item_has_attachments (item, & has_attachment);
-	if (has_attachment) {
-		const GSList *attachment_ids;
-		const EwsId *item_id;
-		EwsAttachmentData *att_data;
-		ECalComponent *comp;
-		const gchar *uid;
+		icalcomp = e_cal_component_get_icalcomponent (comp);
+		icalprop = icalcomponent_get_first_property (icalcomp, ICAL_ATTACH_PROPERTY);
+		for (aid = attachment_ids; aid && icalprop; aid = aid->next, icalprop = icalcomponent_get_next_property (icalcomp, ICAL_ATTACH_PROPERTY)) {
+			icalparam = icalparameter_new_x (aid->data);
+			icalparameter_set_xname (icalparam, "X-EWS-ATTACHMENTID");
+			icalproperty_add_parameter (icalprop, icalparam);
+		}
 
-		item_id = e_ews_item_get_id (item);
-		g_return_if_fail (item_id != NULL);
+		id = e_cal_component_get_id (comp);
+		cache_comp = e_cal_backend_store_get_component (cbews->priv->store, id->uid, id->rid);
+		e_cal_component_free_id (id);
 
-		PRIV_LOCK (cbews->priv);
-		comp = g_hash_table_lookup (cbews->priv->item_id_hash, item_id->id);
-		if (!comp) {
-			PRIV_UNLOCK (cbews->priv);
-			g_warning ("%s: Failed to get component from item_id_hash", G_STRFUNC);
-			return;
-		}
+		put_component_to_store (cbews, comp);
 
-		e_cal_component_get_uid (comp, &uid);
-
-		attachment_ids = e_ews_item_get_attachments_ids (item);
-		att_data = g_new0 (EwsAttachmentData, 1);
-		att_data->cbews = g_object_ref (cbews);
-		att_data->itemid = g_strdup (item_id->id);
-
-		e_ews_connection_get_attachments (
-			cbews->priv->cnc,
-			EWS_PRIORITY_MEDIUM,
-			uid,
-			attachment_ids,
-			cbews->priv->storage_path,
-			TRUE,
-			NULL, NULL,
-			cbews->priv->cancellable,
-			ews_get_attachments_ready_callback,
-			att_data);
+		if (cache_comp)
+			e_cal_backend_notify_component_modified (E_CAL_BACKEND (cbews), cache_comp, comp);
 
-		PRIV_UNLOCK (cbews->priv);
+		g_slist_free_full (uris, g_free);
 	}
 
+	PRIV_UNLOCK (cbews->priv);
 }
 
 static void
 add_item_to_cache (ECalBackendEws *cbews,
-                   EEwsConnection *cnc,
-                   EEwsItem *item)
+                   EEwsItem *item,
+		   GHashTable *ex_to_smtp)
 {
 	ECalBackendEwsPrivate *priv;
 	icalcomponent_kind kind;
@@ -3169,14 +3090,22 @@ add_item_to_cache (ECalBackendEws *cbews,
 				continue;
 
 			if (g_strcmp0 (attendee->mailbox->routing_type, "EX") == 0) {
-				e_ews_connection_ex_to_smtp_sync (
-					cnc, EWS_PRIORITY_MEDIUM,
-					attendee->mailbox->name, attendee->mailbox->email, &email,
-					NULL, NULL);
-
-				/* do not scare users with EX addresses */
-				if (!email)
-					email = g_strdup ("");
+				email = g_hash_table_lookup (ex_to_smtp, attendee->mailbox->email);
+				if (email) {
+					email = g_strdup (email);
+				} else {
+					e_ews_connection_ex_to_smtp_sync (
+						priv->cnc, EWS_PRIORITY_MEDIUM,
+						attendee->mailbox->name, attendee->mailbox->email, &email,
+						NULL, NULL);
+
+					/* do not scare users with EX addresses */
+					if (!email)
+						email = g_strdup ("");
+
+					/* cache value for reuse, because ResolveNames is slow */
+					g_hash_table_insert (ex_to_smtp, g_strdup (attendee->mailbox->email), g_strdup (email));
+				}
 			}
 
 			/*remove organizer for attendees list*/
@@ -3353,36 +3282,36 @@ ews_refreshing_dec (ECalBackendEws *cbews)
 	PRIV_UNLOCK (cbews->priv);
 }
 
-struct _ews_sync_data {
-	ECalBackendEws *cbews;
-	gchar *sync_state;
-	gboolean sync_pending;
-	gchar *master_uid;
-};
-
 static void
-ews_cal_get_items_ready_cb (GObject *obj,
-                            GAsyncResult *res,
-                            gpointer user_data)
+ews_cal_sync_get_items_sync (ECalBackendEws *cbews,
+			     const GSList *item_ids,
+			     const gchar *default_props,
+			     const gchar *additional_props,
+			     GHashTable *ex_to_smtp)
 {
-	EEwsConnection *cnc;
-	ECalBackendEws *cbews;
 	ECalBackendEwsPrivate *priv;
 	GSList *items = NULL, *l;
-	struct _ews_sync_data *sync_data, *sub_sync_data;
 	GError *error = NULL;
 
-	sync_data = (struct _ews_sync_data *) user_data;
-	cbews = sync_data->cbews;
 	priv = cbews->priv;
-	cnc = (EEwsConnection *) obj;
 
-	e_ews_connection_get_items_finish (cnc, res, &items, &error);
-	if (error != NULL) {
-		g_warning ("Unable to get items %s \n", error->message);
+	e_ews_connection_get_items_sync (priv->cnc,
+		EWS_PRIORITY_MEDIUM,
+		item_ids,
+		default_props,
+		additional_props,
+		FALSE,
+		NULL,
+		&items,
+		NULL, NULL,
+		priv->cancellable,
+		&error);
 
+	if (error) {
+		g_debug ("%s: Unable to get items: %s", G_STRFUNC, error->message);
 		g_clear_error (&error);
-		goto exit;
+
+		return;
 	}
 
 	/* fetch modified occurrences */
@@ -3395,23 +3324,10 @@ ews_cal_get_items_ready_cb (GObject *obj,
 
 		modified_occurrences = e_ews_item_get_modified_occurrences (item);
 		if (modified_occurrences) {
-			const EwsId *item_id = e_ews_item_get_id (l->data);
-
-			sub_sync_data = g_new0 (struct _ews_sync_data, 1);
-			sub_sync_data->cbews = g_object_ref (sync_data->cbews);
-			sub_sync_data->master_uid = g_strdup (item_id->id);
-
-			ews_refreshing_inc (cbews);
-
-			e_ews_connection_get_items (
-				g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
-				modified_occurrences,
-				"IdOnly", "item:Attachments item:HasAttachments item:MimeContent calendar:TimeZone calendar:UID calendar:Resources calendar:ModifiedOccurrences calendar:RequiredAttendees calendar:OptionalAttendees",
-				FALSE, NULL, NULL, NULL, priv->cancellable,
-				ews_cal_get_items_ready_cb,
-				(gpointer) sub_sync_data);
-
-			g_object_unref (cnc);
+			ews_cal_sync_get_items_sync (cbews, modified_occurrences,
+				"IdOnly",
+				"item:Attachments item:HasAttachments item:MimeContent calendar:TimeZone calendar:UID calendar:Resources calendar:ModifiedOccurrences calendar:RequiredAttendees calendar:OptionalAttendees",
+				ex_to_smtp);
 		}
 	}
 
@@ -3419,52 +3335,34 @@ ews_cal_get_items_ready_cb (GObject *obj,
 	for (l = items; l != NULL; l = g_slist_next (l)) {
 		EEwsItem *item = (EEwsItem *) l->data;
 
-		if (item && e_ews_item_get_item_type (item) != E_EWS_ITEM_TYPE_ERROR) {
-			add_item_to_cache (cbews, cnc, item);
+		if (!item)
+			continue;
+
+		if (e_ews_item_get_item_type (item) != E_EWS_ITEM_TYPE_ERROR) {
+			add_item_to_cache (cbews, item, ex_to_smtp);
 			ews_get_attachments (cbews, item);
-			g_object_unref (item);
 		}
-	}
-	e_cal_backend_store_thaw_changes (priv->store);
 
-	if (sync_data->sync_state)
-		e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, sync_data->sync_state);
-	if (sync_data->sync_pending) {
-		ews_refreshing_inc (cbews);
-		e_ews_connection_sync_folder_items (
-			g_object_ref (priv->cnc), EWS_PRIORITY_MEDIUM,
-			sync_data->sync_state, priv->folder_id,
-			"IdOnly", NULL,
-			EWS_MAX_FETCH_COUNT,
-			priv->cancellable,
-			ews_cal_sync_items_ready_cb,
-			g_object_ref (cbews));
+		g_object_unref (item);
 	}
+	e_cal_backend_store_thaw_changes (priv->store);
 
- exit:
-	ews_refreshing_dec (cbews);
-
-	g_object_unref (sync_data->cbews);
-	g_free (sync_data->master_uid);
-	g_free (sync_data->sync_state);
-	g_free (sync_data);
+	g_slist_free (items);
 }
 
 static void
-cal_backend_ews_process_folder_items (ECalBackendEws *backend,
-                                      EEwsConnection *connection,
+cal_backend_ews_process_folder_items (ECalBackendEws *cbews,
                                       const gchar *sync_state,
-                                      gboolean includes_last_item,
                                       GSList *items_created,
                                       GSList *items_updated,
-                                      GSList *items_deleted)
+                                      GSList *items_deleted,
+				      GHashTable *ex_to_smtp)
 {
 	ECalBackendEwsPrivate *priv;
 	GSList *l[2], *m, *cal_item_ids = NULL, *task_item_ids = NULL;
-	struct _ews_sync_data *sync_data = NULL;
 	gint i;
 
-	priv = backend->priv;
+	priv = cbews->priv;
 
 	l[0] = items_created;
 	l[1] = items_updated;
@@ -3477,9 +3375,9 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
 
 			id = e_ews_item_get_id (item);
 			if (type == E_EWS_ITEM_TYPE_CALENDAR_ITEM)
-				cal_item_ids = g_slist_append (cal_item_ids, g_strdup (id->id));
+				cal_item_ids = g_slist_prepend (cal_item_ids, id->id);
 			else if (type == E_EWS_ITEM_TYPE_TASK)
-				task_item_ids = g_slist_append (task_item_ids, g_strdup (id->id));
+				task_item_ids = g_slist_prepend (task_item_ids, id->id);
 		}
 	}
 
@@ -3493,180 +3391,110 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
 		PRIV_UNLOCK (priv);
 
 		if (comp)
-			ews_cal_delete_comp (backend, comp, item_id);
+			ews_cal_delete_comp (cbews, comp, item_id);
 	}
 	e_cal_backend_store_thaw_changes (priv->store);
 
-	if (!cal_item_ids && !task_item_ids && !includes_last_item) {
-		e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, sync_state);
-		ews_refreshing_inc (backend);
-		e_ews_connection_sync_folder_items (
-			connection,
-			EWS_PRIORITY_MEDIUM,
-			sync_state, priv->folder_id,
-			"IdOnly", NULL,
-			EWS_MAX_FETCH_COUNT,
-			priv->cancellable,
-			ews_cal_sync_items_ready_cb,
-			g_object_ref (backend));
-		goto exit;
-	}
-
-	if (cal_item_ids || task_item_ids) {
-		sync_data = g_new0 (struct _ews_sync_data, 1);
-		sync_data->cbews = g_object_ref (backend);
-		sync_data->sync_state = g_strdup (sync_state);
-		sync_data->sync_pending = !includes_last_item;
-	}
-
 	if (cal_item_ids) {
-		ews_refreshing_inc (backend);
-		e_ews_connection_get_items (
-			connection,
-			EWS_PRIORITY_MEDIUM,
+		ews_cal_sync_get_items_sync (cbews,
 			cal_item_ids,
 			"IdOnly",
 			"item:Attachments item:HasAttachments item:MimeContent calendar:TimeZone calendar:UID calendar:Resources calendar:ModifiedOccurrences calendar:RequiredAttendees calendar:OptionalAttendees",
-			FALSE, NULL,
-			NULL, NULL, priv->cancellable,
-			ews_cal_get_items_ready_cb,
-			(gpointer) sync_data);
+			ex_to_smtp);
 	}
 
 	if (task_item_ids) {
-		ews_refreshing_inc (backend);
-		e_ews_connection_get_items (
-			connection,
-			EWS_PRIORITY_MEDIUM,
+		ews_cal_sync_get_items_sync (cbews,
 			task_item_ids,
 			"AllProperties",
 			NULL,
-			FALSE,
-			NULL,
-			NULL, NULL, priv->cancellable,
-			ews_cal_get_items_ready_cb,
-			(gpointer) sync_data);
+			ex_to_smtp);
 	}
 
-exit:
-	if (cal_item_ids) {
-		g_slist_foreach (cal_item_ids, (GFunc) g_free, NULL);
-		g_slist_free (cal_item_ids);
-	}
-	if (task_item_ids) {
-		g_slist_foreach (task_item_ids, (GFunc) g_free, NULL);
-		g_slist_free (task_item_ids);
-	}
+	g_slist_free (cal_item_ids);
+	g_slist_free (task_item_ids);
 }
 
-static gboolean
-cal_backend_ews_sync_items_idle_cb (gpointer user_data)
-{
-	SyncItemsClosure *closure = user_data;
-
-	cal_backend_ews_process_folder_items (
-		closure->backend,
-		closure->connection,
-		closure->sync_state,
-		closure->includes_last_item,
-		closure->items_created,
-		closure->items_updated,
-		closure->items_deleted);
-
-	ews_refreshing_dec (closure->backend);
-
-	return FALSE;
-}
-
-static void
-ews_cal_sync_items_ready_cb (GObject *source_object,
-                             GAsyncResult *result,
-                             gpointer user_data)
+static gpointer
+ews_start_sync_thread (gpointer data)
 {
-	ECalBackendEws *backend;
-	EEwsConnection *connection;
+	ECalBackendEws *cbews;
+	ECalBackendEwsPrivate *priv;
 	GSList *items_created = NULL;
 	GSList *items_updated = NULL;
 	GSList *items_deleted = NULL;
 	gboolean includes_last_item;
-	gchar *sync_state = NULL;
+	gchar *old_sync_state = NULL;
+	gchar *new_sync_state = NULL;
+	GHashTable *ex_to_smtp;
 	GError *error = NULL;
 
-	connection = E_EWS_CONNECTION (source_object);
-	backend = E_CAL_BACKEND_EWS (user_data);
-
-	e_ews_connection_sync_folder_items_finish (
-		connection, result,
-		&sync_state,
-		&includes_last_item,
-		&items_created,
-		&items_updated,
-		&items_deleted,
-		&error);
+	cbews = (ECalBackendEws *) data;
+	priv = cbews->priv;
 
-	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-		ews_refreshing_dec (backend);
-		g_error_free (error);
-		g_object_unref (backend);
-		return;
-	}
+	ex_to_smtp = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+	old_sync_state = g_strdup (e_cal_backend_store_get_key_value (priv->store, SYNC_KEY));
+	do {
+		includes_last_item = TRUE;
 
-	/* XXX Why are there two different error codes for cancellation? */
-	if (g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_CANCELLED)) {
-		ews_refreshing_dec (backend);
-		g_error_free (error);
-		g_object_unref (backend);
-		return;
-	}
+		e_ews_connection_sync_folder_items_sync (
+			priv->cnc, EWS_PRIORITY_MEDIUM,
+			old_sync_state, priv->folder_id,
+			"IdOnly", NULL,
+			EWS_MAX_FETCH_COUNT,
+			&new_sync_state,
+			&includes_last_item,
+			&items_created,
+			&items_updated,
+			&items_deleted,
+			priv->cancellable,
+			&error);
 
-	if (!g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED))
-		e_cal_backend_notify_readonly (E_CAL_BACKEND (backend), FALSE);
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+		    g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_CANCELLED)) {
+			break;
+		}
 
-	if (error == NULL) {
-		cal_backend_ews_process_folder_items (
-			backend, connection,
-			sync_state, includes_last_item,
-			items_created, items_updated, items_deleted);
-	} else {
-		g_warn_if_fail (items_created == NULL);
-		g_warn_if_fail (items_updated == NULL);
-		g_warn_if_fail (items_deleted == NULL);
+		if (!g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED))
+			e_cal_backend_notify_readonly (E_CAL_BACKEND (cbews), FALSE);
 
-		g_warning ("%s: %s", G_STRFUNC, error->message);
-		g_error_free (error);
-	}
+		if (error == NULL) {
+			cal_backend_ews_process_folder_items (cbews, new_sync_state,
+				items_created, items_updated, items_deleted,
+				ex_to_smtp);
 
-	ews_refreshing_dec (backend);
+			g_slist_free_full (items_created, (GDestroyNotify) g_object_unref);
+			g_slist_free_full (items_updated, (GDestroyNotify) g_object_unref);
+			g_slist_free_full (items_deleted, (GDestroyNotify) g_free);
+			items_created = NULL;
+			items_updated = NULL;
+			items_deleted = NULL;
+		} else {
+			g_warn_if_fail (items_created == NULL);
+			g_warn_if_fail (items_updated == NULL);
+			g_warn_if_fail (items_deleted == NULL);
 
-	g_slist_free_full (items_created, (GDestroyNotify) g_object_unref);
-	g_slist_free_full (items_updated, (GDestroyNotify) g_object_unref);
-	g_slist_free_full (items_deleted, (GDestroyNotify) g_free);
+			g_warning ("%s: %s", G_STRFUNC, error->message);
+			g_error_free (error);
+			break;
+		}
 
-	g_free (sync_state);
+		g_free (old_sync_state);
+		old_sync_state = new_sync_state;
+		e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, new_sync_state);
+		new_sync_state = NULL;
+	} while (!includes_last_item);
 
-	g_object_unref (backend);
-}
+	ews_refreshing_dec (cbews);
 
-static gpointer
-ews_start_sync_thread (gpointer data)
-{
-	ECalBackendEws *cbews;
-	ECalBackendEwsPrivate *priv;
-	const gchar *sync_state;
+	g_hash_table_destroy (ex_to_smtp);
 
-	cbews = (ECalBackendEws *) data;
-	priv = cbews->priv;
+	g_slist_free_full (items_created, (GDestroyNotify) g_object_unref);
+	g_slist_free_full (items_updated, (GDestroyNotify) g_object_unref);
+	g_slist_free_full (items_deleted, (GDestroyNotify) g_free);
 
-	/* ews_refreshing_inc() is called within ews_start_sync() */
-	sync_state = e_cal_backend_store_get_key_value (priv->store, SYNC_KEY);
-	e_ews_connection_sync_folder_items (
-		priv->cnc, EWS_PRIORITY_MEDIUM,
-		sync_state, priv->folder_id,
-		"IdOnly", NULL,
-		EWS_MAX_FETCH_COUNT,
-		priv->cancellable,
-		ews_cal_sync_items_ready_cb,
-		g_object_ref (cbews));
+	g_free (new_sync_state);
+	g_free (old_sync_state);
 
 	g_object_unref (cbews);
 
@@ -4143,8 +3971,8 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
 	GSList *items_updated = NULL;
 	GSList *items_deleted = NULL;
 	gboolean includes_last_item = FALSE;
-	const gchar *sync_state;
-	gchar *sync_state_inout;
+	const gchar *old_sync_state;
+	gchar *new_sync_state = NULL;
 	gchar *hosturl;
 	GError *local_error = NULL;
 
@@ -4160,16 +3988,16 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
 	g_free (hosturl);
 
 	store = backend->priv->store;
-	sync_state = e_cal_backend_store_get_key_value (store, SYNC_KEY);
-	sync_state_inout = g_strdup (sync_state);
+	old_sync_state = e_cal_backend_store_get_key_value (store, SYNC_KEY);
 
+	/* fetch only up to one item, it's to check whether connection works */
 	e_ews_connection_sync_folder_items_sync (
 		connection,
 		EWS_PRIORITY_MEDIUM,
-		&sync_state_inout,
+		old_sync_state,
 		backend->priv->folder_id,
-		"IdOnly", NULL,
-		EWS_MAX_FETCH_COUNT,
+		"IdOnly", NULL, 1,
+		&new_sync_state,
 		&includes_last_item,
 		&items_created,
 		&items_updated,
@@ -4177,23 +4005,6 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
 		cancellable, &local_error);
 
 	if (local_error == NULL) {
-		SyncItemsClosure *closure;
-
-		/* We can now report the password was accepted.
-		 * Because a password dialog may be stuck in a busy
-		 * state, process the synchronization results from an
-		 * idle callback so we don't delay the authentication
-		 * session any longer than neccessary. */
-
-		/* This takes ownership of the item lists. */
-		closure = g_slice_new0 (SyncItemsClosure);
-		closure->backend = g_object_ref (backend);
-		closure->connection = g_object_ref (connection);
-		closure->includes_last_item = includes_last_item;
-		closure->items_created = items_created;
-		closure->items_deleted = items_deleted;
-		closure->items_updated = items_updated;
-
 		PRIV_LOCK (backend->priv);
 		if (backend->priv->user_email)
 			g_free (backend->priv->user_email);
@@ -4204,12 +4015,11 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
 		backend->priv->cnc = g_object_ref (connection);
 		PRIV_UNLOCK (backend->priv);
 
-		ews_refreshing_inc (backend);
+		g_slist_free_full (items_created, (GDestroyNotify) g_object_unref);
+		g_slist_free_full (items_updated, (GDestroyNotify) g_object_unref);
+		g_slist_free_full (items_deleted, (GDestroyNotify) g_free);
 
-		g_idle_add_full (
-			G_PRIORITY_DEFAULT_IDLE,
-			cal_backend_ews_sync_items_idle_cb, closure,
-			(GDestroyNotify) sync_items_closure_free);
+		ews_start_sync (backend);
 
 		result = E_SOURCE_AUTHENTICATION_ACCEPTED;
 
@@ -4234,7 +4044,7 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
 		}
 	}
 
-	g_free (sync_state_inout);
+	g_free (new_sync_state);
 	g_object_unref (connection);
 
 	return result;
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index 6118581..f459108 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -1427,9 +1427,10 @@ ews_refresh_info_sync (CamelFolder *folder,
 
 		e_ews_connection_sync_folder_items_sync (
 			cnc, EWS_PRIORITY_MEDIUM,
-			&sync_state, id,
+			sync_state, id,
 			"IdOnly", NULL,
-			EWS_MAX_FETCH_COUNT, &includes_last_item,
+			EWS_MAX_FETCH_COUNT,
+			&sync_state, &includes_last_item,
 			&items_created, &items_updated,
 			&items_deleted, cancellable, &local_error);
 
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 4e1f38f..fbbda64 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -3020,7 +3020,7 @@ ews_write_sort_order_to_msg (ESoapMessage *msg,
  * e_ews_connection_sync_folder_items:
  * @cnc: The EWS Connection
  * @pri: The priority associated with the request
- * @sync_state: To sync with the previous requests
+ * @last_sync_state: To sync with the previous requests
  * @folder_id: The folder to which the items belong
  * @default_props: Can take one of the values: IdOnly,Default or AllProperties
  * @additional_props: Specify any additional properties to be fetched
@@ -3032,7 +3032,7 @@ ews_write_sort_order_to_msg (ESoapMessage *msg,
 void
 e_ews_connection_sync_folder_items (EEwsConnection *cnc,
                                     gint pri,
-                                    const gchar *sync_state,
+                                    const gchar *last_sync_state,
                                     const gchar *fid,
                                     const gchar *default_props,
                                     const gchar *additional_props,
@@ -3070,8 +3070,8 @@ e_ews_connection_sync_folder_items (EEwsConnection *cnc,
 	e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", fid);
 	e_soap_message_end_element (msg);
 
-	if (sync_state)
-		e_ews_message_write_string_parameter (msg, "SyncState", "messages", sync_state);
+	if (last_sync_state)
+		e_ews_message_write_string_parameter (msg, "SyncState", "messages", last_sync_state);
 
 	/* Max changes requested */
 	e_ews_message_write_int_parameter (msg, "MaxChangesReturned", "messages", max_entries);
@@ -3097,7 +3097,7 @@ e_ews_connection_sync_folder_items (EEwsConnection *cnc,
 gboolean
 e_ews_connection_sync_folder_items_finish (EEwsConnection *cnc,
                                            GAsyncResult *result,
-                                           gchar **sync_state,
+                                           gchar **new_sync_state,
                                            gboolean *includes_last_item,
                                            GSList **items_created,
                                            GSList **items_updated,
@@ -3119,7 +3119,7 @@ e_ews_connection_sync_folder_items_finish (EEwsConnection *cnc,
 	if (g_simple_async_result_propagate_error (simple, error))
 		return FALSE;
 
-	*sync_state = async_data->sync_state;
+	*new_sync_state = async_data->sync_state;
 	*includes_last_item = async_data->includes_last_item;
 	*items_created = async_data->items_created;
 	*items_updated = async_data->items_updated;
@@ -3131,11 +3131,12 @@ e_ews_connection_sync_folder_items_finish (EEwsConnection *cnc,
 gboolean
 e_ews_connection_sync_folder_items_sync (EEwsConnection *cnc,
                                          gint pri,
-                                         gchar **sync_state,
+                                         const gchar *old_sync_state,
                                          const gchar *fid,
                                          const gchar *default_props,
                                          const gchar *additional_props,
                                          guint max_entries,
+					 gchar **new_sync_state,
                                          gboolean *includes_last_item,
                                          GSList **items_created,
                                          GSList **items_updated,
@@ -3152,14 +3153,14 @@ e_ews_connection_sync_folder_items_sync (EEwsConnection *cnc,
 	closure = e_async_closure_new ();
 
 	e_ews_connection_sync_folder_items (
-		cnc, pri, *sync_state, fid, default_props,
+		cnc, pri, old_sync_state, fid, default_props,
 		additional_props, max_entries, cancellable,
 		e_async_closure_callback, closure);
 
 	result = e_async_closure_wait (closure);
 
 	success = e_ews_connection_sync_folder_items_finish (
-		cnc, result, sync_state, includes_last_item,
+		cnc, result, new_sync_state, includes_last_item,
 		items_created, items_updated, items_deleted, error);
 
 	e_async_closure_free (closure);
@@ -5944,7 +5945,7 @@ GSList *
 e_ews_connection_get_attachments_sync (EEwsConnection *cnc,
                                        gint pri,
                                        const gchar *uid,
-                                       GSList *ids,
+                                       const GSList *ids,
                                        const gchar *cache,
                                        gboolean include_mime,
                                        GSList **items,
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index cf273ad..2fa5180 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -241,7 +241,7 @@ void		ews_delegate_info_free		(EwsDelegateInfo *info);
 void		e_ews_connection_sync_folder_items
 						(EEwsConnection *cnc,
 						 gint pri,
-						 const gchar *sync_state,
+						 const gchar *old_sync_state,
 						 const gchar *fid,
 						 const gchar *default_props,
 						 const gchar *additional_props,
@@ -252,7 +252,7 @@ void		e_ews_connection_sync_folder_items
 gboolean	e_ews_connection_sync_folder_items_finish
 						(EEwsConnection *cnc,
 						 GAsyncResult *result,
-						 gchar **sync_state,
+						 gchar **new_sync_state,
 						 gboolean *includes_last_item,
 						 GSList **items_created,
 						 GSList **items_updated,
@@ -261,11 +261,12 @@ gboolean	e_ews_connection_sync_folder_items_finish
 gboolean	e_ews_connection_sync_folder_items_sync
 						(EEwsConnection *cnc,
 						 gint pri,
-						 gchar **sync_state,
+						 const gchar *old_sync_state,
 						 const gchar *fid,
 						 const gchar *default_props,
 						 const gchar *additional_props,
 						 guint max_entries,
+						 gchar **new_sync_state,
 						 gboolean *includes_last_item,
 						 GSList **items_created,
 						 GSList **items_updated,
@@ -717,7 +718,7 @@ GSList *	e_ews_connection_get_attachments_sync
 						(EEwsConnection *cnc,
 						 gint pri,
 						 const gchar *comp_uid,
-						 GSList *ids,
+						 const GSList *ids,
 						 const gchar *cache,
 						 gboolean include_mime,
 						 GSList **items,



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