[evolution-ews/gnome-3-4] Bug #670458 - Unable to accept meeting request
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/gnome-3-4] Bug #670458 - Unable to accept meeting request
- Date: Tue, 7 Aug 2012 13:21:50 +0000 (UTC)
commit 8efa4ea56c3985b9788aa45a121a4eec4f85b4de
Author: Milan Crha <mcrha redhat com>
Date: Tue Aug 7 15:21:25 2012 +0200
Bug #670458 - Unable to accept meeting request
src/calendar/e-cal-backend-ews.c | 121 ++++++++++++++++++++++++++++++--------
1 files changed, 96 insertions(+), 25 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 357c148..572aa96 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -31,6 +31,7 @@
#include <glib/gi18n-lib.h>
#include "libedataserver/e-xml-hash-utils.h"
#include "libedataserver/e-url.h"
+#include "libedataserver/e-flag.h"
#include <libedata-cal/e-cal-backend-cache.h>
#include <libedata-cal/e-cal-backend-file-store.h>
#include <libedata-cal/e-cal-backend-util.h>
@@ -84,7 +85,8 @@ struct _ECalBackendEwsPrivate {
GStaticRecMutex rec_mutex;
icaltimezone *default_zone;
guint refresh_timeout;
- gboolean refreshing;
+ guint refreshing;
+ EFlag *refreshing_done;
GHashTable *item_id_hash;
ECredentials *credentials;
@@ -670,10 +672,12 @@ e_cal_backend_ews_open_compat (ECalBackend *backend,
ret = e_cal_backend_ews_open (backend, cal, opid, cancellable, only_if_exists, user_name,
password, &error);
- if (!priv->credentials)
+ if (ret && priv->credentials) {
+ e_cal_backend_notify_readonly (backend, FALSE);
+ e_cal_backend_notify_opened (backend, NULL);
+ } else
e_cal_backend_notify_auth_required (backend, TRUE, priv->credentials);
- e_cal_backend_notify_opened (backend, NULL);
convert_error_to_edc_error (&error);
e_data_cal_respond_open (cal, opid, error);
}
@@ -707,6 +711,9 @@ e_cal_backend_ews_authenticate_user (ECalBackend *backend,
connect_to_server (cbews, e_credentials_peek (priv->credentials, E_CREDENTIALS_KEY_USERNAME),
e_credentials_peek (priv->credentials, E_CREDENTIALS_KEY_PASSWORD), &error);
+ if (!error)
+ e_cal_backend_notify_readonly (backend, FALSE);
+
PRIV_UNLOCK (priv);
convert_error_to_edc_error (&error);
@@ -756,10 +763,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);
@@ -770,15 +795,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);
@@ -3256,6 +3279,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;
@@ -3284,10 +3335,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;
}
@@ -3308,6 +3355,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_start (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",
@@ -3332,7 +3381,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_start
(g_object_ref (priv->cnc), EWS_PRIORITY_MEDIUM,
sync_data->sync_state, priv->folder_id,
@@ -3340,8 +3390,11 @@ ews_cal_get_items_ready_cb (GObject *obj,
EWS_MAX_FETCH_COUNT,
ews_cal_sync_items_ready_cb,
NULL, 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);
@@ -3379,9 +3432,7 @@ ews_cal_sync_items_ready_cb (GObject *obj,
if (error != NULL) {
g_warning ("Unable to Sync changes %s \n", error->message);
- PRIV_LOCK (priv);
- priv->refreshing = FALSE;
- PRIV_UNLOCK (priv);
+ ews_refreshing_dec (cbews);
g_clear_error (&error);
g_object_unref (cbews);
@@ -3424,6 +3475,7 @@ ews_cal_sync_items_ready_cb (GObject *obj,
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 (cbews);
e_ews_connection_sync_folder_items_start
(g_object_ref (priv->cnc), EWS_PRIORITY_MEDIUM,
sync_state, priv->folder_id,
@@ -3442,7 +3494,8 @@ ews_cal_sync_items_ready_cb (GObject *obj,
sync_data->sync_pending = !includes_last_item;
}
- if (cal_item_ids)
+ if (cal_item_ids) {
+ ews_refreshing_inc (cbews);
e_ews_connection_get_items_start (cnc,
EWS_PRIORITY_MEDIUM,
cal_item_ids,
@@ -3452,8 +3505,10 @@ ews_cal_sync_items_ready_cb (GObject *obj,
ews_cal_get_items_ready_cb,
NULL, NULL, NULL,
(gpointer) sync_data);
+ }
- if (task_item_ids)
+ if (task_item_ids) {
+ ews_refreshing_inc (cbews);
e_ews_connection_get_items_start (cnc, EWS_PRIORITY_MEDIUM,
task_item_ids,
"AllProperties",
@@ -3463,6 +3518,7 @@ ews_cal_sync_items_ready_cb (GObject *obj,
ews_cal_get_items_ready_cb,
NULL, NULL, NULL,
(gpointer) sync_data);
+ }
exit:
if (cal_item_ids) {
@@ -3481,6 +3537,8 @@ exit:
if (items_deleted)
g_slist_free (items_deleted);
+ ews_refreshing_dec (cbews);
+
g_object_unref (cbews);
}
@@ -3494,10 +3552,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_start
(priv->cnc, EWS_PRIORITY_MEDIUM,
@@ -3515,11 +3570,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;
@@ -3940,6 +4005,11 @@ e_cal_backend_ews_finalize (GObject *object)
e_credentials_free (priv->credentials);
priv->credentials = NULL;
+ if (priv->refreshing_done) {
+ e_flag_free (priv->refreshing_done);
+ priv->refreshing_done = NULL;
+ }
+
g_free (priv);
cbews->priv = NULL;
@@ -3957,6 +4027,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]