[evolution-kolab/ek-wip-porting] E<Cal|Book>BackendKolab: avoid a race condition (fixes #672631)
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting] E<Cal|Book>BackendKolab: avoid a race condition (fixes #672631)
- Date: Thu, 22 Mar 2012 14:59:01 +0000 (UTC)
commit 8aab729174436dd89e4f345db5d989183cd9b35c
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Thu Mar 22 15:49:14 2012 +0100
E<Cal|Book>BackendKolab: avoid a race condition (fixes #672631)
* the hash table of active book/cal views needs to
be shared by all Kolab backend instances of the
same type (calendar/address book)
* access to the hash table which keeps the views is
concurrent when starting and stopping views when
online mode is switched or Evolution is shut down,
so we must serialize access to it by using a lock
src/addressbook/e-book-backend-kolab.c | 51 ++++++++++++++++--------
src/calendar/e-cal-backend-kolab.c | 65 ++++++++++++++++++++-----------
2 files changed, 76 insertions(+), 40 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-kolab.c b/src/addressbook/e-book-backend-kolab.c
index a852fe7..2fa8b25 100644
--- a/src/addressbook/e-book-backend-kolab.c
+++ b/src/addressbook/e-book-backend-kolab.c
@@ -52,6 +52,8 @@
static GHashTable *koma_objects = NULL;
static GMutex *koma_objects_lock = NULL;
+static GHashTable *active_book_views = NULL;
+static GMutex *active_book_views_lock = NULL;
/*----------------------------------------------------------------------------*/
@@ -62,7 +64,6 @@ struct _EBookBackendKolabPrivate
EBookBackendCache *book_cache;
KolabMailAccess *book_koma;
gchar *book_uri;
- GHashTable *active_book_views;
gboolean auth_received;
GError *mode_switch_err;
};
@@ -1081,7 +1082,9 @@ e_book_backend_kolab_start_book_view (EBookBackend *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- bv = g_hash_table_lookup (priv->active_book_views, book_view);
+ g_mutex_lock (active_book_views_lock);
+
+ bv = g_hash_table_lookup (active_book_views, book_view);
if (bv != NULL) {
g_warning ("%s()[%u] book view already active!",
__func__, __LINE__);
@@ -1089,7 +1092,7 @@ e_book_backend_kolab_start_book_view (EBookBackend *backend,
}
g_object_ref (book_view);
- g_hash_table_insert (priv->active_book_views,
+ g_hash_table_insert (active_book_views,
book_view,
NULL);
@@ -1123,17 +1126,21 @@ e_book_backend_kolab_start_book_view (EBookBackend *backend,
exit:
- if (econtact_list != NULL)
- g_list_free (econtact_list);
-
if (tmp_err != NULL) {
kolab_util_contact_err_to_edb_err (¬ify_err, tmp_err, __func__, __LINE__);
g_error_free (tmp_err);
}
e_data_book_view_notify_complete (book_view, notify_err);
+
+ g_mutex_unlock (active_book_views_lock);
+
if (notify_err != NULL)
g_error_free (notify_err);
+
+ if (econtact_list != NULL)
+ g_list_free (econtact_list);
+
}
static void
@@ -1150,15 +1157,20 @@ e_book_backend_kolab_stop_book_view (EBookBackend *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- bv = g_hash_table_lookup (priv->active_book_views, book_view);
+ g_mutex_lock (active_book_views_lock);
+
+ bv = g_hash_table_lookup (active_book_views, book_view);
if (bv == NULL) {
g_warning ("%s()[%u] book view already stopped!",
__func__, __LINE__);
- return;
+ goto exit;
}
e_data_book_view_notify_complete (book_view, NULL);
- g_hash_table_remove (priv->active_book_views, book_view);
+ g_hash_table_remove (active_book_views, book_view);
+
+ exit:
+ g_mutex_unlock (active_book_views_lock);
}
/*----------------------------------------------------------------------------*/
@@ -1190,16 +1202,25 @@ e_book_backend_kolab_init (EBookBackendKolab *backend)
g_free,
g_object_unref);
g_mutex_unlock (koma_objects_lock);
+ /* active cal views are shared in the same way,
+ * so we do the housekeeping for them analogous
+ * to the KolabMailAccess instances
+ */
+ if (active_book_views_lock == NULL)
+ active_book_views_lock = g_mutex_new ();
+ g_mutex_lock (active_book_views_lock);
+ if (active_book_views == NULL)
+ active_book_views = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ g_object_unref,
+ NULL);
+ g_mutex_unlock (active_book_views_lock);
g_debug ("%s()[%u] called.", __func__, __LINE__);
priv->book_cache = NULL;
priv->book_uri = NULL;
priv->book_koma = NULL;
- priv->active_book_views = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- g_object_unref,
- NULL);
priv->auth_received = FALSE;
priv->mode_switch_err = NULL;
@@ -1234,10 +1255,6 @@ e_book_backend_kolab_dispose (GObject *object)
g_object_unref (priv->book_cache);
priv->book_cache = NULL;
}
- if (priv->active_book_views != NULL) {
- g_hash_table_destroy (priv->active_book_views);
- priv->active_book_views = NULL;
- }
}
static void
diff --git a/src/calendar/e-cal-backend-kolab.c b/src/calendar/e-cal-backend-kolab.c
index 173c020..61937b7 100644
--- a/src/calendar/e-cal-backend-kolab.c
+++ b/src/calendar/e-cal-backend-kolab.c
@@ -52,6 +52,8 @@
static GHashTable *koma_objects = NULL;
static GMutex *koma_objects_lock = NULL;
+static GHashTable *active_cal_views = NULL;
+static GMutex *active_cal_views_lock = NULL;
/*----------------------------------------------------------------------------*/
/* forward declarations */
@@ -92,7 +94,6 @@ struct _ECalBackendKolabPrivate {
CalMode cal_mode;
KolabMailAccess *cal_koma;
ECalBackendCache *cal_cache;
- GHashTable *active_cal_views;
gchar *user_email;
ECalComponent *default_zone;
ECalSourceType source_type;
@@ -1747,15 +1748,17 @@ e_cal_backend_kolab_start_view (ECalBackend *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- cv = g_hash_table_lookup (priv->active_cal_views, view);
+ g_mutex_lock (active_cal_views_lock);
+
+ cv = g_hash_table_lookup (active_cal_views, view);
if (cv != NULL) {
g_warning ("%s()[%u] cal view already active!",
__func__, __LINE__);
- return;
+ goto exit;
}
g_object_ref (view);
- g_hash_table_insert (priv->active_cal_views,
+ g_hash_table_insert (active_cal_views,
view,
NULL);
@@ -1809,15 +1812,8 @@ e_cal_backend_kolab_start_view (ECalBackend *backend,
e_data_cal_view_notify_objects_added (view,
iCal_objects);
+
exit:
- if (iCal_objects != NULL) {
- g_slist_foreach (iCal_objects, (GFunc) g_free, NULL);
- g_slist_free (iCal_objects);
- }
- if (sourcename != NULL)
- g_free (sourcename);
- if (uid_list != NULL)
- kolab_util_glib_glist_free (uid_list);
if (tmp_err != NULL) {
kolab_util_calendar_err_to_edb_err (&view_err, tmp_err, __func__, __LINE__);
@@ -1825,8 +1821,21 @@ e_cal_backend_kolab_start_view (ECalBackend *backend,
}
e_data_cal_view_notify_complete (view, view_err);
+
+ g_mutex_unlock (active_cal_views_lock);
+
if (view_err != NULL)
g_error_free (view_err);
+
+ if (iCal_objects != NULL) {
+ g_slist_foreach (iCal_objects, (GFunc) g_free, NULL);
+ g_slist_free (iCal_objects);
+ }
+ if (sourcename != NULL)
+ g_free (sourcename);
+ if (uid_list != NULL)
+ kolab_util_glib_glist_free (uid_list);
+
}
static void
@@ -1843,15 +1852,20 @@ e_cal_backend_kolab_stop_view (ECalBackend *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- cv = g_hash_table_lookup (priv->active_cal_views, view);
+ g_mutex_lock (active_cal_views_lock);
+
+ cv = g_hash_table_lookup (active_cal_views, view);
if (cv == NULL) {
g_warning ("%s()[%u] cal view already stopped!",
__func__, __LINE__);
- return;
+ goto exit;
}
e_data_cal_view_notify_complete (view, NULL);
- g_hash_table_remove (priv->active_cal_views, view);
+ g_hash_table_remove (active_cal_views, view);
+
+ exit:
+ g_mutex_unlock (active_cal_views_lock);
}
static void
@@ -1902,6 +1916,19 @@ e_cal_backend_kolab_init (ECalBackendKolab *backend)
g_free,
g_object_unref);
g_mutex_unlock (koma_objects_lock);
+ /* active cal views are shared in the same way,
+ * so we do the housekeeping for them analogous
+ * to the KolabMailAccess instances
+ */
+ if (active_cal_views_lock == NULL)
+ active_cal_views_lock = g_mutex_new ();
+ g_mutex_lock (active_cal_views_lock);
+ if (active_cal_views == NULL)
+ active_cal_views = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ g_object_unref,
+ NULL);
+ g_mutex_unlock (active_cal_views_lock);
g_debug ("%s()[%u] called.", __func__, __LINE__);
@@ -1913,10 +1940,6 @@ e_cal_backend_kolab_init (ECalBackendKolab *backend)
priv->source_type = 0;
priv->cal_uri = NULL;
priv->mode_switch_err = NULL;
- priv->active_cal_views = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- g_object_unref,
- NULL);
g_signal_connect (E_BACKEND (backend), "notify::online", G_CALLBACK (cal_backend_kolab_signal_online_cb), NULL);
} /* e_cal_backend_kolab_init () */
@@ -1944,10 +1967,6 @@ e_cal_backend_kolab_dispose (GObject *object)
g_object_unref (priv->cal_cache);
priv->cal_cache = NULL;
}
- if (priv->active_cal_views != NULL) {
- g_hash_table_destroy (priv->active_cal_views);
- priv->active_cal_views = NULL;
- }
G_OBJECT_CLASS (e_cal_backend_kolab_parent_class)->dispose (object);
} /* e_cal_backend_kolab_dispose () */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]