[evolution-ews] Bug #670458 - Unable to accept meeting request
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #670458 - Unable to accept meeting request
- Date: Tue, 7 Aug 2012 13:21:07 +0000 (UTC)
commit 344f8748e32a584bba0068dbc32e0809a082f71c
Author: Milan Crha <mcrha redhat com>
Date: Tue Aug 7 15:20:19 2012 +0200
Bug #670458 - Unable to accept meeting request
src/calendar/e-cal-backend-ews.c | 120 ++++++++++++++++++++++++++++++--------
1 files changed, 96 insertions(+), 24 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 4227279..36877b7 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -83,7 +83,8 @@ struct _ECalBackendEwsPrivate {
GStaticRecMutex rec_mutex;
icaltimezone *default_zone;
guint refresh_timeout;
- gboolean refreshing;
+ guint refreshing;
+ EFlag *refreshing_done;
GHashTable *item_id_hash;
GCancellable *cancellable;
@@ -666,6 +667,9 @@ e_cal_backend_ews_open (ECalBackend *backend,
E_SOURCE_AUTHENTICATOR (backend),
cancellable, &error);
+ if (!error)
+ e_cal_backend_notify_readonly (backend, FALSE);
+
convert_error_to_edc_error (&error);
e_cal_backend_respond_opened (backend, cal, opid, error);
}
@@ -713,10 +717,28 @@ e_cal_backend_ews_get_object (ECalBackend *backend,
PRIV_LOCK (priv);
+ /* make sure any pending refreshing is done */
+ while (priv->refreshing) {
+ PRIV_UNLOCK (priv);
+ e_flag_wait (priv->refreshing_done);
+ PRIV_LOCK (priv);
+ }
+
/* search the object in the cache */
comp = e_cal_backend_store_get_component (priv->store, uid, rid);
- if (comp) {
+ if (!comp) {
+ /* maybe a meeting invitation, for which the calendar item is not downloaded yet,
+ thus synchronize local cache first */
+ ews_start_sync (cbews);
+
PRIV_UNLOCK (priv);
+ e_flag_wait (priv->refreshing_done);
+ PRIV_LOCK (priv);
+
+ comp = e_cal_backend_store_get_component (priv->store, uid, rid);
+ }
+
+ if (comp) {
if (e_cal_backend_get_kind (backend) ==
icalcomponent_isa (e_cal_component_get_icalcomponent (comp)))
object = e_cal_component_get_as_string (comp);
@@ -727,15 +749,13 @@ e_cal_backend_ews_get_object (ECalBackend *backend,
if (!object)
g_propagate_error (&error, EDC_ERROR (ObjectNotFound));
- goto exit;
+ } else {
+ g_propagate_error (&error, EDC_ERROR (ObjectNotFound));
}
PRIV_UNLOCK (priv);
- /* callers will never have a uuid that is in server but not in cache */
- g_propagate_error (&error, EDC_ERROR (ObjectNotFound));
-
-exit:
+ exit:
convert_error_to_edc_error (&error);
e_data_cal_respond_get_object (cal, context, error, object);
g_free (object);
@@ -3325,6 +3345,34 @@ add_item_to_cache (ECalBackendEws *cbews,
icalcomponent_free (vcomp);
}
+static void
+ews_refreshing_inc (ECalBackendEws *cbews)
+{
+ PRIV_LOCK (cbews->priv);
+ if (!cbews->priv->refreshing)
+ e_flag_clear (cbews->priv->refreshing_done);
+ cbews->priv->refreshing++;
+ PRIV_UNLOCK (cbews->priv);
+}
+
+static void
+ews_refreshing_dec (ECalBackendEws *cbews)
+{
+ PRIV_LOCK (cbews->priv);
+ if (!cbews->priv->refreshing) {
+ e_flag_set (cbews->priv->refreshing_done);
+ PRIV_UNLOCK (cbews->priv);
+
+ g_warning ("%s: Invalid call, currently not refreshing", G_STRFUNC);
+ return;
+ }
+ cbews->priv->refreshing--;
+ if (!cbews->priv->refreshing) {
+ e_flag_set (cbews->priv->refreshing_done);
+ }
+ PRIV_UNLOCK (cbews->priv);
+}
+
struct _ews_sync_data {
ECalBackendEws *cbews;
gchar *sync_state;
@@ -3353,10 +3401,6 @@ ews_cal_get_items_ready_cb (GObject *obj,
if (error != NULL) {
g_warning ("Unable to get items %s \n", error->message);
- PRIV_LOCK (priv);
- priv->refreshing = FALSE;
- PRIV_UNLOCK (priv);
-
g_clear_error (&error);
goto exit;
}
@@ -3377,6 +3421,8 @@ ews_cal_get_items_ready_cb (GObject *obj,
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,
@@ -3403,7 +3449,8 @@ ews_cal_get_items_ready_cb (GObject *obj,
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)
+ 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,
@@ -3412,8 +3459,11 @@ ews_cal_get_items_ready_cb (GObject *obj,
priv->cancellable,
ews_cal_sync_items_ready_cb,
g_object_ref (cbews));
+ }
+
+ exit:
+ ews_refreshing_dec (cbews);
-exit:
g_object_unref (sync_data->cbews);
g_free (sync_data->master_uid);
g_free (sync_data->sync_state);
@@ -3469,6 +3519,7 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
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,
@@ -3488,7 +3539,8 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
sync_data->sync_pending = !includes_last_item;
}
- if (cal_item_ids)
+ if (cal_item_ids) {
+ ews_refreshing_inc (backend);
e_ews_connection_get_items (
connection,
EWS_PRIORITY_MEDIUM,
@@ -3499,8 +3551,10 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
NULL, NULL, priv->cancellable,
ews_cal_get_items_ready_cb,
(gpointer) sync_data);
+ }
- if (task_item_ids)
+ if (task_item_ids) {
+ ews_refreshing_inc (backend);
e_ews_connection_get_items (
connection,
EWS_PRIORITY_MEDIUM,
@@ -3512,6 +3566,7 @@ cal_backend_ews_process_folder_items (ECalBackendEws *backend,
NULL, NULL, priv->cancellable,
ews_cal_get_items_ready_cb,
(gpointer) sync_data);
+ }
exit:
if (cal_item_ids) {
@@ -3538,6 +3593,8 @@ cal_backend_ews_sync_items_idle_cb (gpointer user_data)
closure->items_updated,
closure->items_deleted);
+ ews_refreshing_dec (closure->backend);
+
return FALSE;
}
@@ -3568,6 +3625,7 @@ ews_cal_sync_items_ready_cb (GObject *source_object,
&error);
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;
@@ -3575,6 +3633,7 @@ ews_cal_sync_items_ready_cb (GObject *source_object,
/* 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;
@@ -3593,14 +3652,12 @@ ews_cal_sync_items_ready_cb (GObject *source_object,
g_warn_if_fail (items_updated == NULL);
g_warn_if_fail (items_deleted == NULL);
- PRIV_LOCK (backend->priv);
- backend->priv->refreshing = FALSE;
- PRIV_UNLOCK (backend->priv);
-
g_warning ("%s: %s", G_STRFUNC, error->message);
g_error_free (error);
}
+ 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);
@@ -3620,10 +3677,7 @@ ews_start_sync_thread (gpointer data)
cbews = (ECalBackendEws *) data;
priv = cbews->priv;
- PRIV_LOCK (priv);
- priv->refreshing = TRUE;
- PRIV_UNLOCK (priv);
-
+ /* 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,
@@ -3642,11 +3696,21 @@ ews_start_sync_thread (gpointer data)
static gboolean
ews_start_sync (gpointer data)
{
+ ECalBackendEws *cbews = data;
GThread *thread;
+ PRIV_LOCK (cbews->priv);
+ if (cbews->priv->refreshing) {
+ PRIV_UNLOCK (cbews->priv);
+ return TRUE;
+ }
+
+ ews_refreshing_inc (cbews);
+ PRIV_UNLOCK (cbews->priv);
+
/* run the actual operation in thread,
* to not block main thread of the factory */
- thread = g_thread_new (NULL, ews_start_sync_thread, g_object_ref (data));
+ thread = g_thread_new (NULL, ews_start_sync_thread, g_object_ref (cbews));
g_thread_unref (thread);
return TRUE;
@@ -4073,6 +4137,11 @@ e_cal_backend_ews_finalize (GObject *object)
g_hash_table_destroy (priv->item_id_hash);
+ if (priv->refreshing_done) {
+ e_flag_free (priv->refreshing_done);
+ priv->refreshing_done = NULL;
+ }
+
g_free (priv);
cbews->priv = NULL;
@@ -4145,6 +4214,8 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
closure->items_deleted = items_deleted;
closure->items_updated = items_updated;
+ ews_refreshing_inc (backend);
+
g_idle_add_full (
G_PRIORITY_DEFAULT_IDLE,
cal_backend_ews_sync_items_idle_cb, closure,
@@ -4241,6 +4312,7 @@ e_cal_backend_ews_init (ECalBackendEws *cbews)
/* create the mutex for thread safety */
g_static_rec_mutex_init (&priv->rec_mutex);
+ priv->refreshing_done = e_flag_new ();
priv->item_id_hash = g_hash_table_new_full
(g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]