[evolution-kolab/ek-wip-porting: 6/6] E<Cal|Book>BackendKolab: avoid a race condition (fixes #672614)
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting: 6/6] E<Cal|Book>BackendKolab: avoid a race condition (fixes #672614)
- Date: Thu, 22 Mar 2012 10:59:49 +0000 (UTC)
commit 47a2bdec7d362fbe12ae7efdf6365b10f94cfab2
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Thu Mar 22 11:55:30 2012 +0100
E<Cal|Book>BackendKolab: avoid a race condition (fixes #672614)
* the hash table of KolabMailAccess instances is shared
by all Kolab backend instances of the same type
(calendar/address book)
* access to this data structure is concurrent when
opening calendars or address books, so we must
serialize access to it by using a lock
src/addressbook/e-book-backend-kolab.c | 217 +++++++++++++++-----------------
src/calendar/e-cal-backend-kolab.c | 199 +++++++++++++++--------------
2 files changed, 204 insertions(+), 212 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-kolab.c b/src/addressbook/e-book-backend-kolab.c
index 2ec0f50..a852fe7 100644
--- a/src/addressbook/e-book-backend-kolab.c
+++ b/src/addressbook/e-book-backend-kolab.c
@@ -51,6 +51,7 @@
/* table of KolabMailAccess objects */
static GHashTable *koma_objects = NULL;
+static GMutex *koma_objects_lock = NULL;
/*----------------------------------------------------------------------------*/
@@ -61,7 +62,6 @@ struct _EBookBackendKolabPrivate
EBookBackendCache *book_cache;
KolabMailAccess *book_koma;
gchar *book_uri;
- GHashTable *koma_table;
GHashTable *active_book_views;
gboolean auth_received;
GError *mode_switch_err;
@@ -206,7 +206,7 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
- ESource *source = NULL;
+ ESource *esource = NULL;
CamelURL *c_url = NULL;
KolabSettingsHandler *ksettings = NULL;
KolabMailAccess *tmp_koma = NULL;
@@ -216,8 +216,9 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
gchar *username = NULL;
gchar *user_at_server = NULL;
gchar *tmp_key = NULL;
- const gchar *sync_prop = NULL;
+ const gchar *prop_str = NULL;
gboolean online = FALSE;
+ gboolean auth_required = FALSE;
gboolean ok = FALSE;
GError *tmp_err = NULL;
@@ -230,47 +231,31 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- kolab_util_glib_init ();
- kolab_util_http_init ();
- /* libcamel
- * Curl init may configure the underlying SSL lib,
- * but as far as SSL goes, we want Camel to rule here
- * TODO check whether Camel session needs to be initialized before or after libcurl.
+ g_mutex_lock (koma_objects_lock);
+
+ /* to trigger eds to pass along username and password, set the property
+ * "auth" to "true" in the source setting:
+ * <property name="auth" value="true"/>
+ * <property name="username" value="..."/>
*/
- ok = kolab_util_camel_init (&tmp_err);
- if (! ok) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
- source = e_backend_get_source (E_BACKEND (backend));
- if (! E_IS_SOURCE (source)) {
- /* FIXME is this E_DATA_BOOK_STATUS_NO_SUCH_BOOK ? */
+ esource = e_backend_get_source (E_BACKEND (backend));
+ if (! E_IS_SOURCE (esource)) {
/* FIXME mark this as a translatable string */
tmp_err = e_data_book_create_error (E_DATA_BOOK_STATUS_OTHER_ERROR,
"Could not get ESource for backend");
- g_propagate_error (error, tmp_err);
- return;
+ goto exit;
}
- priv->book_uri = e_source_get_uri (source);
- g_debug ("%s()[%u] uri = %s",
- __func__, __LINE__, priv->book_uri);
-
+ priv->book_uri = e_source_get_uri (esource);
c_url = camel_url_new (priv->book_uri, &tmp_err);
- if (c_url == NULL) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (c_url == NULL)
+ goto exit;
+
servername = g_strdup (c_url->host);
username = g_strdup (c_url->user);
- camel_url_free (c_url);
- g_debug ("%s()[%u] servername = %s",
- __func__, __LINE__, servername);
- g_debug ("%s()[%u] username = %s",
- __func__, __LINE__, username);
+ g_debug ("%s()[%u] servername = %s", __func__, __LINE__, servername);
+ g_debug ("%s()[%u] username = %s", __func__, __LINE__, username);
/* Initialize backend cache */
if (priv->book_cache != NULL) {
@@ -281,19 +266,18 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
g_debug (" + Book cache cleaning %s.", ok ? "was successful" : "FAILED");
/* Prepare data from sync strategy property */
- sync_prop = e_source_get_property (source, KOLAB_SYNC_STRATEGY_PROP);
- sync_value = kolab_util_misc_sync_value_from_property (sync_prop);
+ prop_str = e_source_get_property (esource, KOLAB_SYNC_STRATEGY_PROP);
+ sync_value = kolab_util_misc_sync_value_from_property (prop_str);
sourcename = kolab_util_backend_get_relative_path_from_uri (priv->book_uri);
/* Check whether we have a KolabMailAccess (KoMA) instance already */
-
user_at_server = g_strdup_printf ("%s %s",
username, servername);
-
- ok = g_hash_table_lookup_extended (priv->koma_table,
+ ok = g_hash_table_lookup_extended (koma_objects,
user_at_server,
(gpointer *) &tmp_key,
(gpointer *) &tmp_koma);
+
if (ok) {
gchar *passwd = NULL;
@@ -302,9 +286,6 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
*/
g_object_ref (tmp_koma);
priv->book_koma = tmp_koma;
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
ksettings = kolab_mail_access_get_settings_handler (priv->book_koma);
kolab_util_backend_prepare_settings (ksettings,
NULL,
@@ -313,7 +294,6 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
NULL,
sourcename,
&sync_value);
-
/* We may find that we do not yet have a password set.
* In case we're requested to go online, we will need
* one, so we need to get authentication data first.
@@ -321,10 +301,9 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
passwd = g_strdup (kolab_settings_handler_get_char_field (ksettings,
KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_PASSWORD,
NULL));
- g_object_unref (ksettings);
if (passwd == NULL) {
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (self), TRUE, NULL);
- return;
+ auth_required = TRUE;
+ goto exit;
}
g_free (passwd);
@@ -332,85 +311,64 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
online,
cancellable,
&tmp_err);
- if (tmp_err != NULL) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
- ok = book_backend_kolab_notify_opened (self, &tmp_err);
- if (! ok) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- }
- return;
+ goto exit;
}
/* Nope, we need to setup a new KoMA instance and a settings handler */
+ /* init subsystems (these are no-ops if already called before) */
+ kolab_util_glib_init ();
+ kolab_util_http_init ();
+ /* libcamel
+ * Curl init may configure the underlying SSL lib,
+ * but as far as SSL goes, we want Camel to rule here
+ * TODO check whether Camel session needs to be initialized before or after libcurl.
+ */
+ ok = kolab_util_camel_init (&tmp_err);
+ if (! ok)
+ goto exit;
+
/* Configure settings handler */
ksettings = KOLAB_SETTINGS_HANDLER (g_object_new (KOLAB_TYPE_SETTINGS_HANDLER, NULL));
ok = kolab_settings_handler_configure (ksettings,
KOLAB_FOLDER_CONTEXT_CONTACT,
&tmp_err);
- if (! ok) {
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
- g_object_unref (ksettings);
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
ok = kolab_settings_handler_bringup (ksettings, &tmp_err);
- if (! ok) {
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
- g_object_unref (ksettings);
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
kolab_util_backend_prepare_settings (ksettings,
- source,
+ esource,
servername,
username,
NULL,
sourcename,
&sync_value);
- g_free (servername);
- g_free (username);
- g_free (sourcename);
-
+ /* create new KolabMailAccess instance */
priv->book_koma = KOLAB_MAIL_ACCESS (g_object_new (KOLAB_TYPE_MAIL_ACCESS, NULL));
g_object_add_toggle_ref (G_OBJECT (priv->book_koma),
kolab_util_backend_koma_table_cleanup_cb,
- priv->koma_table);
- g_hash_table_insert (priv->koma_table,
+ koma_objects);
+ g_hash_table_insert (koma_objects,
user_at_server,
priv->book_koma);
+ /* configure and bring up KolabMailAccess instance */
ok = kolab_mail_access_configure (priv->book_koma,
ksettings,
&tmp_err);
- g_object_unref (ksettings);
- if (! ok) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
ok = kolab_mail_access_bringup (priv->book_koma,
cancellable,
&tmp_err);
- if (! ok) {
- kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
/* If we are here (just created a fresh KolabMailAccess),
* we did not yet receive authentication data. Though we
@@ -419,24 +377,43 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
* (password in our case) anyway, so we can just request
* it once the book gets opened.
*/
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (self), TRUE, NULL);
+ auth_required = TRUE;
- /* FIXME may need to move the notifications to authenticate_user() */
-#if 0
- /* e_book_backend_kolab_set_mode (backend, priv->book_mode); */
- tmp_mode = kolab_mail_access_get_opmode (priv->book_koma, &tmp_err);
+ exit:
+
+ if (ksettings != NULL)
+ g_object_unref (ksettings);
+
+ g_mutex_unlock (koma_objects_lock);
+
+ if (c_url != NULL)
+ camel_url_free (c_url);
+ if (servername != NULL)
+ g_free (servername);
+ if (username != NULL)
+ g_free (username);
+ if (user_at_server != NULL)
+ g_free (user_at_server);
+
+ /* do we have an error set? if so, propagate and return */
if (tmp_err != NULL) {
kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
g_error_free (tmp_err);
return;
}
- e_book_backend_set_is_loaded (bbackend, TRUE);
- e_book_backend_notify_connection_status (bbackend,
- tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE ? TRUE : FALSE);
- e_book_backend_set_is_writable (bbackend, TRUE);
- e_book_backend_notify_writable (bbackend, TRUE);
-#endif
+ /* do we need authentication data? if so, notify and return */
+ if (auth_required) {
+ e_book_backend_notify_auth_required (E_BOOK_BACKEND (self), TRUE, NULL);
+ return;
+ }
+
+ /* all good, notify that we're open for business */
+ ok = book_backend_kolab_notify_opened (self, &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
}
static void
@@ -1192,16 +1169,30 @@ e_book_backend_kolab_init (EBookBackendKolab *backend)
{
EBookBackendKolabPrivate *priv = E_BOOK_BACKEND_KOLAB_PRIVATE (backend);
- g_debug ("%s()[%u] called.", __func__, __LINE__);
-
+ /* We're inside a thread, and each of our siblings
+ * (other configured ECalBackendKolab instances) is
+ * so as well. Depending on how the threads are
+ * started, checking for lock existence (and creating
+ * one if it is not) in *this* place can still be
+ * racy. Let's hope the threads are started one
+ * at a time, in which case this solution will work.
+ * The whole handling of living KolabMailAccess
+ * instances would better be moved to a separate
+ * library...
+ *
+ */
+ if (koma_objects_lock == NULL)
+ koma_objects_lock = g_mutex_new ();
+ g_mutex_lock (koma_objects_lock);
if (koma_objects == NULL)
- koma_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- else
- g_hash_table_ref (koma_objects);
+ koma_objects = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ g_free,
+ g_object_unref);
+ g_mutex_unlock (koma_objects_lock);
- priv->koma_table = koma_objects;
+ g_debug ("%s()[%u] called.", __func__, __LINE__);
- /* priv->book_mode = E_DATA_BOOK_MODE_LOCAL; */ /* Start in local mode for now. */
priv->book_cache = NULL;
priv->book_uri = NULL;
priv->book_koma = NULL;
@@ -1237,10 +1228,6 @@ e_book_backend_kolab_dispose (GObject *object)
g_object_unref (priv->book_koma);
priv->book_koma = NULL;
}
- if (priv->koma_table != NULL) {
- g_hash_table_unref (koma_objects);
- priv->koma_table = NULL;
- }
#endif
if (priv->book_cache != NULL) {
(void) e_file_cache_remove (E_FILE_CACHE (priv->book_cache));
diff --git a/src/calendar/e-cal-backend-kolab.c b/src/calendar/e-cal-backend-kolab.c
index 85d5056..173c020 100644
--- a/src/calendar/e-cal-backend-kolab.c
+++ b/src/calendar/e-cal-backend-kolab.c
@@ -51,6 +51,7 @@
/* table of KolabMailAccess objects */
static GHashTable *koma_objects = NULL;
+static GMutex *koma_objects_lock = NULL;
/*----------------------------------------------------------------------------*/
/* forward declarations */
@@ -88,7 +89,6 @@ typedef struct {
/* Private part of the ECalBackendKolab structure */
typedef struct _ECalBackendKolabPrivate ECalBackendKolabPrivate;
struct _ECalBackendKolabPrivate {
- GHashTable *koma_table;
CalMode cal_mode;
KolabMailAccess *cal_koma;
ECalBackendCache *cal_cache;
@@ -248,6 +248,7 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
gchar *tmp_key = NULL;
const gchar *prop_str = NULL;
gboolean online = FALSE;
+ gboolean auth_required = FALSE;
gboolean ok = FALSE;
GError *tmp_err = NULL;
@@ -260,6 +261,8 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
self = E_CAL_BACKEND_KOLAB (backend);
priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
+ g_mutex_lock (koma_objects_lock);
+
/* to trigger eds to pass along username and password, set the property
* "auth" to "true" in the source setting:
* <property name="auth" value="true"/>
@@ -279,23 +282,11 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
priv->source_type = E_CAL_SOURCE_TYPE_JOURNAL;
break;
default:
- /* FIXME */
- g_error ("%s()[%u]: Unknown Type used in e-cal-backend-kolab initialization!",
- __func__, __LINE__);
- }
-
- kolab_util_glib_init ();
- kolab_util_http_init ();
- /* libcamel
- * Curl init may configure the underlying SSL lib,
- * but as far as SSL goes, we want Camel to rule here
- * TODO check whether Camel session needs to be initialized before or after libcurl.
- */
- ok = kolab_util_camel_init (&tmp_err);
- if (! ok) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
+ g_set_error (&tmp_err,
+ KOLAB_BACKEND_ERROR,
+ KOLAB_BACKEND_ERROR_GENERIC,
+ "Unknown type used in e-cal-backend-kolab initialization");
+ goto exit;
}
esource = e_backend_get_source (E_BACKEND (backend));
@@ -303,25 +294,18 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
/* FIXME mark this as a translatable string */
tmp_err = e_data_cal_create_error (OtherError,
"Could not get ESource for backend");
- g_propagate_error (error, tmp_err);
- return;
+ goto exit;
}
priv->cal_uri = e_source_get_uri (esource);
-
c_url = camel_url_new (priv->cal_uri, &tmp_err);
- if (c_url == NULL) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (c_url == NULL)
+ goto exit;
+
servername = g_strdup (c_url->host);
username = g_strdup (c_url->user);
- camel_url_free (c_url);
- g_debug ("%s()[%u] servername = %s",
- __func__, __LINE__, servername);
- g_debug ("%s()[%u] username = %s",
- __func__, __LINE__, username);
+ g_debug ("%s()[%u] servername = %s", __func__, __LINE__, servername);
+ g_debug ("%s()[%u] username = %s", __func__, __LINE__, username);
/* Initialize backend cache */
if (priv->cal_cache != NULL) {
@@ -337,14 +321,13 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
sourcename = kolab_util_backend_get_relative_path_from_uri (priv->cal_uri);
/* Check whether we have a KolabMailAccess (KoMA) instance already */
-
user_at_server = g_strdup_printf ("%s %s",
username, servername);
-
- ok = g_hash_table_lookup_extended (priv->koma_table,
+ ok = g_hash_table_lookup_extended (koma_objects,
user_at_server,
(gpointer *) &tmp_key,
(gpointer *) &tmp_koma);
+
if (ok) {
gchar *passwd = NULL;
@@ -353,9 +336,6 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
*/
g_object_ref (tmp_koma);
priv->cal_koma = tmp_koma;
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
ksettings = kolab_mail_access_get_settings_handler (priv->cal_koma);
kolab_util_backend_prepare_settings (ksettings,
NULL,
@@ -371,10 +351,9 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
passwd = g_strdup (kolab_settings_handler_get_char_field (ksettings,
KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_PASSWORD,
NULL));
- g_object_unref (ksettings);
if (passwd == NULL) {
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (self), TRUE, NULL);
- return;
+ auth_required = TRUE;
+ goto exit;
}
g_free (passwd);
@@ -382,46 +361,34 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
online,
cancellable,
&tmp_err);
- if (tmp_err != NULL) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
- ok = cal_backend_kolab_notify_opened (self, &tmp_err);
- if (! ok) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- }
- return;
+ goto exit;
}
/* Nope, we need to setup a new KoMA instance and a settings handler */
+ /* init subsystems (these are no-ops if already called before) */
+ kolab_util_glib_init ();
+ kolab_util_http_init ();
+ /* libcamel
+ * Curl init may configure the underlying SSL lib,
+ * but as far as SSL goes, we want Camel to rule here
+ * TODO check whether Camel session needs to be initialized before or after libcurl.
+ */
+ ok = kolab_util_camel_init (&tmp_err);
+ if (! ok)
+ goto exit;
+
/* Configure settings handler */
ksettings = KOLAB_SETTINGS_HANDLER (g_object_new (KOLAB_TYPE_SETTINGS_HANDLER, NULL));
ok = kolab_settings_handler_configure (ksettings,
KOLAB_FOLDER_CONTEXT_CALENDAR,
&tmp_err);
- if (! ok) {
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
- g_object_unref (ksettings);
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
ok = kolab_settings_handler_bringup (ksettings, &tmp_err);
- if (! ok) {
- g_free (servername);
- g_free (username);
- g_free (user_at_server);
- g_object_unref (ksettings);
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
kolab_util_backend_prepare_settings (ksettings,
esource,
@@ -431,36 +398,27 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
sourcename,
&sync_value);
- g_free (servername);
- g_free (username);
- g_free (sourcename);
-
+ /* create new KolabMailAccess instance */
priv->cal_koma = KOLAB_MAIL_ACCESS (g_object_new (KOLAB_TYPE_MAIL_ACCESS, NULL));
g_object_add_toggle_ref (G_OBJECT (priv->cal_koma),
kolab_util_backend_koma_table_cleanup_cb,
- priv->koma_table);
- g_hash_table_insert (priv->koma_table,
+ koma_objects);
+ g_hash_table_insert (koma_objects,
user_at_server,
priv->cal_koma);
+ /* configure and bring up KolabMailAccess instance */
ok = kolab_mail_access_configure (priv->cal_koma,
ksettings,
&tmp_err);
- g_object_unref (ksettings);
- if (! ok) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
ok = kolab_mail_access_bringup (priv->cal_koma,
cancellable,
&tmp_err);
- if (! ok) {
- kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
- g_error_free (tmp_err);
- return;
- }
+ if (! ok)
+ goto exit;
/* TODO this is sort of hackish, we cannot be sure that
* 'user server' is truly the Kolab email address
@@ -475,7 +433,43 @@ e_cal_backend_kolab_open (ECalBackendSync *backend,
* (password in our case) anyway, so we can just request
* it once the book gets opened.
*/
- e_cal_backend_notify_auth_required (E_CAL_BACKEND (self), TRUE, NULL);
+ auth_required = TRUE;
+
+ exit:
+
+ if (ksettings != NULL)
+ g_object_unref (ksettings);
+
+ g_mutex_unlock (koma_objects_lock);
+
+ if (c_url != NULL)
+ camel_url_free (c_url);
+ if (servername != NULL)
+ g_free (servername);
+ if (username != NULL)
+ g_free (username);
+ if (user_at_server != NULL)
+ g_free (user_at_server);
+
+ /* do we have an error set? if so, propagate and return */
+ if (tmp_err != NULL) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
+ /* do we need authentication data? if so, notify and return */
+ if (auth_required) {
+ e_cal_backend_notify_auth_required (E_CAL_BACKEND (self), TRUE, NULL);
+ return;
+ }
+
+ /* all good, notify that we're open for business */
+ ok = cal_backend_kolab_notify_opened (self, &tmp_err);
+ if (! ok) {
+ kolab_util_calendar_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
}
static void
@@ -1887,14 +1881,29 @@ e_cal_backend_kolab_init (ECalBackendKolab *backend)
ECalBackendKolab *self = E_CAL_BACKEND_KOLAB (backend);
ECalBackendKolabPrivate *priv = E_CAL_BACKEND_KOLAB_PRIVATE (self);
- g_debug ("%s()[%u] called.", __func__, __LINE__);
-
+ /* We're inside a thread, and each of our siblings
+ * (other configured ECalBackendKolab instances) is
+ * so as well. Depending on how the threads are
+ * started, checking for lock existence (and creating
+ * one if it is not) in *this* place can still be
+ * racy. Let's hope the threads are started one
+ * at a time, in which case this solution will work.
+ * The whole handling of living KolabMailAccess
+ * instances would better be moved to a separate
+ * library...
+ *
+ */
+ if (koma_objects_lock == NULL)
+ koma_objects_lock = g_mutex_new ();
+ g_mutex_lock (koma_objects_lock);
if (koma_objects == NULL)
- koma_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- else
- g_hash_table_ref (koma_objects);
+ koma_objects = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ g_free,
+ g_object_unref);
+ g_mutex_unlock (koma_objects_lock);
- priv->koma_table = koma_objects;
+ g_debug ("%s()[%u] called.", __func__, __LINE__);
priv->cal_mode = 0;
priv->cal_koma = NULL;
@@ -1926,10 +1935,6 @@ e_cal_backend_kolab_dispose (GObject *object)
g_object_unref (priv->cal_koma);
priv->cal_koma = NULL;
}
- if (priv->koma_table != NULL) {
- g_hash_table_unref (priv->koma_table);
- priv->koma_table = NULL;
- }
#endif
if (priv->default_zone != NULL) {
g_object_unref (priv->default_zone);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]