[evolution-data-server] Bug #597648 - Crash due to DBus used from more threads in one time



commit 2f753106418c9d31bd4a71295e90fc741ab59338
Author: Milan Crha <mcrha redhat com>
Date:   Fri Nov 13 11:35:45 2009 +0100

    Bug #597648 - Crash due to DBus used from more threads in one time

 addressbook/libebook/e-book-view-private.h |    2 +-
 addressbook/libebook/e-book-view.c         |   30 ++++--
 addressbook/libebook/e-book.c              |  175 +++++++++++++++++++++++-----
 calendar/libecal/e-cal-view-private.h      |    2 +-
 calendar/libecal/e-cal-view.c              |   43 +++++--
 calendar/libecal/e-cal.c                   |  129 +++++++++++++++++++--
 6 files changed, 319 insertions(+), 62 deletions(-)
---
diff --git a/addressbook/libebook/e-book-view-private.h b/addressbook/libebook/e-book-view-private.h
index 8b7db45..b6dcb57 100644
--- a/addressbook/libebook/e-book-view-private.h
+++ b/addressbook/libebook/e-book-view-private.h
@@ -25,7 +25,7 @@
 #include "e-book.h"
 #include "e-book-view.h"
 
-EBookView *_e_book_view_new (EBook *book, DBusGProxy *view_proxy);
+EBookView *_e_book_view_new (EBook *book, DBusGProxy *view_proxy, GStaticRecMutex *connection_lock);
 
 G_END_DECLS
 
diff --git a/addressbook/libebook/e-book-view.c b/addressbook/libebook/e-book-view.c
index f5c1460..6b03068 100644
--- a/addressbook/libebook/e-book-view.c
+++ b/addressbook/libebook/e-book-view.c
@@ -36,6 +36,7 @@ G_DEFINE_TYPE(EBookView, e_book_view, G_TYPE_OBJECT);
 struct _EBookViewPrivate {
 	EBook *book;
 	DBusGProxy *view_proxy;
+	GStaticRecMutex *view_proxy_lock;
 	gboolean running;
 };
 
@@ -128,6 +129,9 @@ complete_cb (DBusGProxy *proxy, guint status, EBookView *book_view)
 	g_signal_emit (book_view, signals[SEQUENCE_COMPLETE], 0, status);
 }
 
+#define LOCK_CONN()   g_static_rec_mutex_lock (book_view->priv->view_proxy_lock)
+#define UNLOCK_CONN() g_static_rec_mutex_unlock (book_view->priv->view_proxy_lock)
+
 /*
  * e_book_view_new:
  * @book: an #EBook
@@ -140,7 +144,7 @@ complete_cb (DBusGProxy *proxy, guint status, EBookView *book_view)
  * Return value: A new #EBookView.
  **/
 EBookView *
-_e_book_view_new (EBook *book, DBusGProxy *view_proxy)
+_e_book_view_new (EBook *book, DBusGProxy *view_proxy, GStaticRecMutex *view_proxy_lock)
 {
 	EBookView *view;
 	EBookViewPrivate *priv;
@@ -152,6 +156,7 @@ _e_book_view_new (EBook *book, DBusGProxy *view_proxy)
 
 	/* Take ownership of the view_proxy object */
 	priv->view_proxy = view_proxy;
+	priv->view_proxy_lock = view_proxy_lock;
 	g_object_add_weak_pointer (G_OBJECT (view_proxy), (gpointer)&priv->view_proxy);
 
 	dbus_g_proxy_add_signal (view_proxy, "StatusMessage", G_TYPE_STRING, G_TYPE_INVALID);
@@ -200,7 +205,9 @@ e_book_view_start (EBookView *book_view)
 	book_view->priv->running = TRUE;
 
 	if (book_view->priv->view_proxy) {
+		LOCK_CONN ();
 		org_gnome_evolution_dataserver_addressbook_BookView_start (book_view->priv->view_proxy, &error);
+		UNLOCK_CONN ();
 		if (error) {
 			g_warning ("Cannot start book view: %s\n", error->message);
 
@@ -230,7 +237,9 @@ e_book_view_stop (EBookView *book_view)
 	book_view->priv->running = FALSE;
 
 	if (book_view->priv->view_proxy) {
+		LOCK_CONN ();
 		org_gnome_evolution_dataserver_addressbook_BookView_stop (book_view->priv->view_proxy, &error);
+		UNLOCK_CONN ();
 		if (error) {
 			g_warning ("Cannot stop book view: %s\n", error->message);
 			g_error_free (error);
@@ -245,6 +254,7 @@ e_book_view_init (EBookView *book_view)
 
 	priv->book = NULL;
 	priv->view_proxy = NULL;
+	priv->view_proxy_lock = NULL;
 	priv->running = FALSE;
 
 	book_view->priv = priv;
@@ -253,17 +263,19 @@ e_book_view_init (EBookView *book_view)
 static void
 e_book_view_dispose (GObject *object)
 {
-	EBookView *view = E_BOOK_VIEW (object);
+	EBookView *book_view = E_BOOK_VIEW (object);
 
-	if (view->priv->view_proxy) {
-		org_gnome_evolution_dataserver_addressbook_BookView_dispose (view->priv->view_proxy, NULL);
-		g_object_unref (view->priv->view_proxy);
-		view->priv->view_proxy = NULL;
+	if (book_view->priv->view_proxy) {
+		LOCK_CONN ();
+		org_gnome_evolution_dataserver_addressbook_BookView_dispose (book_view->priv->view_proxy, NULL);
+		g_object_unref (book_view->priv->view_proxy);
+		book_view->priv->view_proxy = NULL;
+		UNLOCK_CONN ();
 	}
 
-	if (view->priv->book) {
-		g_object_unref (view->priv->book);
-		view->priv->book = NULL;
+	if (book_view->priv->book) {
+		g_object_unref (book_view->priv->book);
+		book_view->priv->book = NULL;
 	}
 }
 
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index b05bf37..1701264 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -70,6 +70,11 @@ struct _EBookPrivate {
 static DBusGConnection *connection = NULL;
 static DBusGProxy *factory_proxy = NULL;
 
+/* guards both connection and factory_proxy */
+static GStaticRecMutex connection_lock = G_STATIC_REC_MUTEX_INIT;
+#define LOCK_CONN()   g_static_rec_mutex_lock (&connection_lock)
+#define UNLOCK_CONN() g_static_rec_mutex_unlock (&connection_lock)
+
 typedef struct {
 	EBook *book;
 	gpointer callback; /* TODO union */
@@ -100,8 +105,10 @@ proxy_destroyed (gpointer data, GObject *object)
 	g_warning (G_STRLOC ": e-d-s proxy died");
 
 	/* Ensure that everything relevant is NULL */
+	LOCK_CONN ();
 	factory_proxy = NULL;
 	book->priv->proxy = NULL;
+	UNLOCK_CONN ();
 
 	g_signal_emit (G_OBJECT (book), e_book_signals [BACKEND_DIED], 0);
 }
@@ -115,16 +122,16 @@ e_book_dispose (GObject *object)
 
 	if (book->priv->proxy) {
 		g_object_weak_unref (G_OBJECT (book->priv->proxy), proxy_destroyed, book);
+		LOCK_CONN ();
 		org_gnome_evolution_dataserver_addressbook_Book_close (book->priv->proxy, NULL);
+		g_object_unref (book->priv->proxy);
+		book->priv->proxy = NULL;
+		UNLOCK_CONN ();
 	}
 	if (book->priv->source) {
 		g_object_unref (book->priv->source);
 		book->priv->source = NULL;
 	}
-	if (book->priv->proxy) {
-		g_object_unref (book->priv->proxy);
-		book->priv->proxy = NULL;
-	}
 
 	if (G_OBJECT_CLASS (e_book_parent_class)->dispose)
 		G_OBJECT_CLASS (e_book_parent_class)->dispose (object);
@@ -214,14 +221,19 @@ e_book_activate(GError **error)
 {
 	DBusError derror;
 
+	LOCK_CONN ();
+
 	if (G_LIKELY (factory_proxy)) {
+		UNLOCK_CONN ();
 		return TRUE;
 	}
 
 	if (!connection) {
 		connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
-		if (!connection)
+		if (!connection) {
+			UNLOCK_CONN ();
 			return FALSE;
+		}
 	}
 
 	dbus_error_init (&derror);
@@ -230,6 +242,7 @@ e_book_activate(GError **error)
 					     0, NULL, &derror)) {
 		dbus_set_g_error (error, &derror);
 		dbus_error_free (&derror);
+		UNLOCK_CONN ();
 		return FALSE;
 	}
 
@@ -240,11 +253,13 @@ e_book_activate(GError **error)
 								 "org.gnome.evolution.dataserver.addressbook.BookFactory",
 								 error);
 		if (!factory_proxy) {
+			UNLOCK_CONN ();
 			return FALSE;
 		}
 		g_object_add_weak_pointer (G_OBJECT (factory_proxy), (gpointer)&factory_proxy);
 	}
 
+	UNLOCK_CONN ();
 	return TRUE;
 }
 
@@ -299,7 +314,9 @@ e_book_add_contact (EBook           *book,
 	e_return_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
 
 	vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_add_contact (book->priv->proxy, vcard, &uid, &err);
+	UNLOCK_CONN ();
 	g_free (vcard);
 	if (uid) {
 		e_contact_set (contact, E_CONTACT_UID, uid);
@@ -360,7 +377,9 @@ e_book_async_add_contact (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_add_contact_async (book->priv->proxy, vcard, add_contact_reply, data);
+	UNLOCK_CONN ();
 	g_free (vcard);
 	return 0;
 }
@@ -389,7 +408,9 @@ e_book_commit_contact (EBook           *book,
 	e_return_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
 
 	vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_modify_contact (book->priv->proxy, vcard, &err);
+	UNLOCK_CONN ();
 	g_free (vcard);
 	return unwrap_gerror (err, error);
 }
@@ -439,7 +460,9 @@ e_book_async_commit_contact (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_modify_contact_async (book->priv->proxy, vcard, modify_contact_reply, data);
+	UNLOCK_CONN ();
 	g_free (vcard);
 	return 0;
 }
@@ -468,7 +491,9 @@ e_book_get_required_fields  (EBook            *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_required_fields (book->priv->proxy, &list, &err);
+	UNLOCK_CONN ();
 	if (list) {
 		*fields = array_to_stringlist (list);
 		return TRUE;
@@ -526,7 +551,9 @@ e_book_async_get_required_fields (EBook              *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_required_fields_async (book->priv->proxy, get_required_fields_reply, data);
+	UNLOCK_CONN ();
 	return 0;
 }
 
@@ -554,7 +581,9 @@ e_book_get_supported_fields  (EBook            *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_supported_fields (book->priv->proxy, &list, &err);
+	UNLOCK_CONN ();
 	if (list) {
 		*fields = array_to_stringlist (list);
 		return TRUE;
@@ -612,7 +641,10 @@ e_book_async_get_supported_fields (EBook              *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_supported_fields_async (book->priv->proxy, get_supported_fields_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -639,7 +671,9 @@ e_book_get_supported_auth_methods (EBook            *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_supported_auth_methods (book->priv->proxy, &list, &err);
+	UNLOCK_CONN ();
 	if (list) {
 		*auth_methods = array_to_stringlist (list);
 		return TRUE;
@@ -688,18 +722,21 @@ e_book_async_get_supported_auth_methods (EBook              *book,
 					 EBookEListCallback  cb,
 					 gpointer            closure)
 {
-	 AsyncData *data;
+	AsyncData *data;
+
+	e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+	e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
-	 e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
-	 e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
+	data = g_slice_new0 (AsyncData);
+	data->book = g_object_ref (book);
+	data->callback = cb;
+	data->closure = closure;
 
-	 data = g_slice_new0 (AsyncData);
-	 data->book = g_object_ref (book);
-	 data->callback = cb;
-	 data->closure = closure;
+	LOCK_CONN ();
+	org_gnome_evolution_dataserver_addressbook_Book_get_supported_auth_methods_async (book->priv->proxy, get_supported_auth_methods_reply, data);
+	UNLOCK_CONN ();
 
-	 org_gnome_evolution_dataserver_addressbook_Book_get_supported_auth_methods_async (book->priv->proxy, get_supported_auth_methods_reply, data);
-	 return 0;
+	return 0;
  }
 
 /**
@@ -728,7 +765,10 @@ e_book_authenticate_user (EBook         *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_authenticate_user (book->priv->proxy, user, passwd, auth_method, &err);
+	UNLOCK_CONN ();
+
 	return unwrap_gerror (err, error);
 }
 
@@ -782,7 +822,10 @@ e_book_async_authenticate_user (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_authenticate_user_async (book->priv->proxy, user, passwd, auth_method, authenticate_user_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -810,7 +853,10 @@ e_book_get_contact (EBook       *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_contact (book->priv->proxy, id, &vcard, &err);
+	UNLOCK_CONN ();
+
 	if (vcard) {
 		*contact = e_contact_new_from_vcard (vcard);
 		g_free (vcard);
@@ -874,7 +920,10 @@ e_book_async_get_contact (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_contact_async (book->priv->proxy, id, get_contact_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -903,7 +952,10 @@ e_book_remove_contact (EBook       *book,
 	l[0] = id;
 	l[1] = NULL;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove_contacts (book->priv->proxy, l, &err);
+	UNLOCK_CONN ();
+
 	return unwrap_gerror (err, error);
 }
 
@@ -947,8 +999,12 @@ e_book_remove_contacts (EBook    *book,
 
 	l = flatten_stringlist (ids);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove_contacts (book->priv->proxy, (const gchar **) l, &err);
+	UNLOCK_CONN ();
+
 	g_free (l);
+
 	return unwrap_gerror (err, error);
 }
 
@@ -969,23 +1025,26 @@ e_book_async_remove_contact (EBook                 *book,
 			     EBookCallback          cb,
 			     gpointer               closure)
 {
-	 AsyncData *data;
-	 const gchar *l[2];
+	AsyncData *data;
+	const gchar *l[2];
 
-	 e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
-	 e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
-	 e_return_async_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
+	e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+	e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
+	e_return_async_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
 
-	 l[0] = e_contact_get_const (contact, E_CONTACT_UID);
-	 l[1] = NULL;
+	l[0] = e_contact_get_const (contact, E_CONTACT_UID);
+	l[1] = NULL;
 
-	 data = g_slice_new0 (AsyncData);
-	 data->book = g_object_ref (book);
-	 data->callback = cb;
-	 data->closure = closure;
+	data = g_slice_new0 (AsyncData);
+	data->book = g_object_ref (book);
+	data->callback = cb;
+	data->closure = closure;
 
-	 org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, l, remove_contact_reply, data);
-	 return 0;
+	LOCK_CONN ();
+	org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, l, remove_contact_reply, data);
+	UNLOCK_CONN ();
+
+	return 0;
  }
 
 static void
@@ -1033,7 +1092,10 @@ e_book_async_remove_contact_by_id (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, l, remove_contact_by_id_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -1089,8 +1151,12 @@ e_book_async_remove_contacts (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, (const gchar **) l, remove_contacts_reply, data);
+	UNLOCK_CONN ();
+
 	g_free (l);
+
 	return 0;
 }
 
@@ -1127,7 +1193,9 @@ e_book_get_book_view (EBook       *book,
 
 	sexp = e_book_query_to_string (query);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_addressbook_Book_get_book_view (book->priv->proxy, sexp, max_results, &view_path, &err)) {
+		UNLOCK_CONN ();
 		*book_view = NULL;
 		g_free (sexp);
 		return unwrap_gerror (err, error);
@@ -1135,9 +1203,10 @@ e_book_get_book_view (EBook       *book,
 	view_proxy = dbus_g_proxy_new_for_name_owner (connection,
 						      E_DATA_BOOK_FACTORY_SERVICE_NAME, view_path,
 						      "org.gnome.evolution.dataserver.addressbook.BookView", error);
+	UNLOCK_CONN ();
 
 	if (view_proxy) {
-		*book_view = _e_book_view_new (book, view_proxy);
+		*book_view = _e_book_view_new (book, view_proxy, &connection_lock);
 	} else {
 		*book_view = NULL;
 		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
@@ -1162,10 +1231,12 @@ get_book_view_reply (DBusGProxy *proxy, gchar *view_path, GError *error, gpointe
 	EBookStatus status;
 
 	if (view_path) {
+		LOCK_CONN ();
 		view_proxy = dbus_g_proxy_new_for_name_owner (connection, E_DATA_BOOK_FACTORY_SERVICE_NAME, view_path,
 							      "org.gnome.evolution.dataserver.addressbook.BookView", &err);
+		UNLOCK_CONN ();
 		if (view_proxy) {
-			view = _e_book_view_new (data->book, view_proxy);
+			view = _e_book_view_new (data->book, view_proxy, &connection_lock);
 			status = E_BOOK_ERROR_OK;
 		} else {
 			g_warning (G_STRLOC ": cannot get connection to view: %s", err->message);
@@ -1219,7 +1290,9 @@ e_book_async_get_book_view (EBook                 *book,
 
 	sexp = e_book_query_to_string (query);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_book_view_async (book->priv->proxy, sexp, max_results, get_book_view_reply, data);
+	UNLOCK_CONN ();
 
 	g_free (sexp);
 	return 0;
@@ -1250,7 +1323,9 @@ e_book_get_contacts (EBook       *book,
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
 	sexp = e_book_query_to_string (query);
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_contact_list (book->priv->proxy, sexp, &list, &err);
+	UNLOCK_CONN ();
 	g_free (sexp);
 	if (!err) {
 		GList *l = NULL;
@@ -1319,7 +1394,9 @@ e_book_async_get_contacts (EBook             *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_contact_list_async (book->priv->proxy, sexp, get_contacts_reply, data);
+	UNLOCK_CONN ();
 	g_free (sexp);
 	return 0;
 }
@@ -1377,7 +1454,9 @@ e_book_get_changes (EBook       *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_changes (book->priv->proxy, changeid, &array, &err);
+	UNLOCK_CONN ();
 	if (!err) {
 		*changes = parse_changes_array (array);
 		return TRUE;
@@ -1431,7 +1510,10 @@ e_book_async_get_changes (EBook             *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_get_changes_async (book->priv->proxy, changeid, get_changes_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -1476,10 +1558,16 @@ gboolean
 e_book_cancel (EBook   *book,
 	       GError **error)
 {
+	gboolean res;
+
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
-	return org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error);
+	LOCK_CONN ();
+	res = org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error);
+	UNLOCK_CONN ();
+
+	return res;
 }
 
 /**
@@ -1490,10 +1578,16 @@ e_book_cancel (EBook   *book,
 gboolean
 e_book_cancel_async_op (EBook *book, GError **error)
 {
+	gboolean res;
+
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
-	return org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error);
+	LOCK_CONN ();
+	res = org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error);
+	UNLOCK_CONN ();
+
+	return res;
 }
 
 /**
@@ -1517,10 +1611,13 @@ e_book_open (EBook     *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_addressbook_Book_open (book->priv->proxy, only_if_exists, &err)) {
+		UNLOCK_CONN ();
 		g_propagate_error (error, err);
 		return FALSE;
 	}
+	UNLOCK_CONN ();
 
 	status = get_status_from_error (err);
 
@@ -1579,7 +1676,10 @@ e_book_async_open (EBook                 *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_open_async (book->priv->proxy, only_if_exists, open_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -1602,7 +1702,10 @@ e_book_remove (EBook   *book,
 	e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
 	e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE);
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove (book->priv->proxy, &err);
+	UNLOCK_CONN ();
+
 	return unwrap_gerror (err, error);
 }
 
@@ -1644,7 +1747,10 @@ e_book_async_remove (EBook   *book,
 	data->callback = cb;
 	data->closure = closure;
 
+	LOCK_CONN ();
 	org_gnome_evolution_dataserver_addressbook_Book_remove_async (book->priv->proxy, remove_reply, data);
+	UNLOCK_CONN ();
+
 	return 0;
 }
 
@@ -1700,9 +1806,12 @@ e_book_get_static_capabilities (EBook   *book,
 	if (!book->priv->cap_queried) {
 		gchar *cap = NULL;
 
+		LOCK_CONN ();
 		if (!org_gnome_evolution_dataserver_addressbook_Book_get_static_capabilities (book->priv->proxy, &cap, error)) {
+			UNLOCK_CONN ();
 			return NULL;
 		}
+		UNLOCK_CONN ();
 
 		book->priv->cap = cap;
 		book->priv->cap_queried = TRUE;
@@ -2051,7 +2160,9 @@ e_book_new (ESource *source, GError **error)
 
 	xml = e_source_to_standalone_xml (source);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_addressbook_BookFactory_get_book (factory_proxy, xml, &path, &err)) {
+		UNLOCK_CONN ();
 		g_free (xml);
 		g_warning (G_STRLOC ": cannot get book from factory: %s", err ? err->message : "[no error]");
 		g_propagate_error (error, err);
@@ -2064,6 +2175,8 @@ e_book_new (ESource *source, GError **error)
 							     E_DATA_BOOK_FACTORY_SERVICE_NAME, path,
 							     "org.gnome.evolution.dataserver.addressbook.Book",
 							     &err);
+	UNLOCK_CONN ();
+
 	if (!book->priv->proxy) {
 		g_warning (G_STRLOC ": cannot get proxy for book %s: %s", path, err->message);
 		g_propagate_error (error, err);
diff --git a/calendar/libecal/e-cal-view-private.h b/calendar/libecal/e-cal-view-private.h
index 073c9ee..e542702 100644
--- a/calendar/libecal/e-cal-view-private.h
+++ b/calendar/libecal/e-cal-view-private.h
@@ -28,7 +28,7 @@
 
 G_BEGIN_DECLS
 
-ECalView *e_cal_view_new (DBusGProxy *view_proxy, struct _ECal *client);
+ECalView *_e_cal_view_new (struct _ECal *client, DBusGProxy *view_proxy, GStaticRecMutex *connection_lock);
 
 G_END_DECLS
 
diff --git a/calendar/libecal/e-cal-view.c b/calendar/libecal/e-cal-view.c
index 54baf23..b17e51a 100644
--- a/calendar/libecal/e-cal-view.c
+++ b/calendar/libecal/e-cal-view.c
@@ -35,9 +35,13 @@
 G_DEFINE_TYPE(ECalView, e_cal_view, G_TYPE_OBJECT);
 #define E_CAL_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL_VIEW, ECalViewPrivate))
 
+#define LOCK_VIEW()   g_static_rec_mutex_lock (priv->view_proxy_lock)
+#define UNLOCK_VIEW() g_static_rec_mutex_unlock (priv->view_proxy_lock)
+
 /* Private part of the ECalView structure */
 struct _ECalViewPrivate {
 	DBusGProxy *view_proxy;
+	GStaticRecMutex *view_proxy_lock;
 	ECal *client;
 };
 
@@ -45,6 +49,7 @@ struct _ECalViewPrivate {
 enum props {
 	PROP_0,
 	PROP_VIEW,
+	PROP_VIEW_LOCK,
 	PROP_CLIENT
 };
 
@@ -222,6 +227,9 @@ e_cal_view_set_property (GObject *object, guint property_id, const GValue *value
                 dbus_g_proxy_connect_signal (priv->view_proxy, "Done", G_CALLBACK (done_cb), view, NULL);
 
 		break;
+	case PROP_VIEW_LOCK:
+		priv->view_proxy_lock = g_value_get_pointer (value);
+		break;
 	case PROP_CLIENT:
 		priv->client = E_CAL (g_value_dup_object (value));
 		break;
@@ -244,6 +252,9 @@ e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GPar
 	case PROP_VIEW:
 		g_value_set_pointer (value, priv->view_proxy);
 		break;
+	case PROP_VIEW_LOCK:
+		g_value_set_pointer (value, priv->view_proxy_lock);
+		break;
 	case PROP_CLIENT:
 		g_value_set_object (value, priv->client);
 		break;
@@ -280,7 +291,6 @@ static void
 e_cal_view_class_init (ECalViewClass *klass)
 {
 	GObjectClass *object_class;
-	GParamSpec *param;
 
 	object_class = (GObjectClass *) klass;
 
@@ -292,12 +302,17 @@ e_cal_view_class_init (ECalViewClass *klass)
 
 	g_type_class_add_private (klass, sizeof (ECalViewPrivate));
 
-	param =  g_param_spec_pointer ("view", "The DBus view proxy", NULL,
-				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
-	g_object_class_install_property (object_class, PROP_VIEW, param);
-	param =  g_param_spec_object ("client", "The e-cal for the view", NULL, E_TYPE_CAL,
-				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
-	g_object_class_install_property (object_class, PROP_CLIENT, param);
+	g_object_class_install_property (object_class, PROP_VIEW,
+		g_param_spec_pointer ("view", "The DBus view proxy", NULL,
+				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class, PROP_VIEW_LOCK,
+		g_param_spec_pointer ("view-lock", "The DBus view proxy lock", NULL,
+				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class, PROP_CLIENT,
+		g_param_spec_object ("client", "The e-cal for the view", NULL, E_TYPE_CAL,
+				      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
 	signals[OBJECTS_ADDED] =
 		g_signal_new ("objects_added",
@@ -342,7 +357,7 @@ e_cal_view_class_init (ECalViewClass *klass)
 }
 
 /**
- * e_cal_view_new:
+ * _e_cal_view_new:
  * @corba_view: The CORBA object for the view.
  * @client: An #ECal object.
  *
@@ -352,11 +367,15 @@ e_cal_view_class_init (ECalViewClass *klass)
  * Return value: A newly-created view object, or NULL if the request failed.
  **/
 ECalView *
-e_cal_view_new (DBusGProxy *view_proxy, ECal *client)
+_e_cal_view_new (ECal *client, DBusGProxy *view_proxy, GStaticRecMutex *connection_lock)
 {
 	ECalView *view;
 
-	view = g_object_new (E_TYPE_CAL_VIEW, "view", view_proxy, "client", client, NULL);
+	view = g_object_new (E_TYPE_CAL_VIEW,
+		"client", client,
+		"view", view_proxy,
+		"view-lock", connection_lock,
+		NULL);
 
 	return view;
 }
@@ -394,9 +413,13 @@ e_cal_view_start (ECalView *view)
 
 	priv = E_CAL_VIEW_GET_PRIVATE(view);
 
+	LOCK_VIEW ();
 	if (!org_gnome_evolution_dataserver_calendar_CalView_start (priv->view_proxy, &error)) {
+		UNLOCK_VIEW ();
 		g_printerr("%s: %s\n", __FUNCTION__, error->message);
 		g_error_free (error);
 		g_warning (G_STRLOC ": Unable to start view");
+		return;
 	}
+	UNLOCK_VIEW ();
 }
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index ecf0e68..1a87439 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -50,6 +50,11 @@
 static DBusGConnection *connection = NULL;
 static DBusGProxy *factory_proxy = NULL;
 
+/* guards both connection and factory_proxy */
+static GStaticRecMutex connection_lock = G_STATIC_REC_MUTEX_INIT;
+#define LOCK_CONN()   g_static_rec_mutex_lock (&connection_lock)
+#define UNLOCK_CONN() g_static_rec_mutex_unlock (&connection_lock)
+
 G_DEFINE_TYPE(ECal, e_cal, G_TYPE_OBJECT)
 #define E_CAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL, ECalPrivate))
 
@@ -382,13 +387,24 @@ e_cal_dispose (GObject *object)
 {
 	ECal *ecal;
 	ECalPrivate *priv;
-	GError *error = NULL;
 
 	ecal = E_CAL (object);
 	priv = ecal->priv;
 
-	if (priv->proxy)
+	if (priv->proxy) {
+		GError *error = NULL;
+
+		LOCK_CONN ();
 		org_gnome_evolution_dataserver_calendar_Cal_close (priv->proxy, &error);
+		g_object_unref (priv->proxy);
+		priv->proxy = NULL;
+		UNLOCK_CONN ();
+
+		if (error) {
+			g_warning ("%s: Failed to close calendar, %s\n", G_STRFUNC, error->message);
+			g_error_free (error);
+		}
+	}
 
 	(* G_OBJECT_CLASS (parent_class)->dispose) (object);
 }
@@ -514,16 +530,20 @@ e_cal_class_init (ECalClass *klass)
 static gboolean
 e_cal_activate(GError **error)
 {
-	static gboolean done = FALSE;
 	DBusError derror;
 
-	if (G_LIKELY(done))
+	LOCK_CONN ();
+	if (G_LIKELY (factory_proxy)) {
+		UNLOCK_CONN ();
 		return TRUE;
+	}
 
 	if (!connection) {
 		connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
-		if (!connection)
+		if (!connection) {
+			UNLOCK_CONN ();
 			return FALSE;
+		}
 	}
 
 	dbus_error_init (&derror);
@@ -533,6 +553,7 @@ e_cal_activate(GError **error)
 	{
 		dbus_set_g_error (error, &derror);
 		dbus_error_free (&derror);
+		UNLOCK_CONN ();
 		return FALSE;
 	}
 
@@ -542,11 +563,14 @@ e_cal_activate(GError **error)
 							"/org/gnome/evolution/dataserver/calendar/CalFactory",
 							"org.gnome.evolution.dataserver.calendar.CalFactory",
 							error);
-		if (!factory_proxy)
+		if (!factory_proxy) {
+			UNLOCK_CONN ();
 			return FALSE;
+		}
 	}
 
-	done = TRUE;
+	UNLOCK_CONN ();
+
 	return TRUE;
 }
 
@@ -742,7 +766,9 @@ e_cal_new (ESource *source, ECalSourceType type)
 	priv->type = type;
 
 	xml = e_source_to_standalone_xml (priv->source);
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_CalFactory_get_cal (factory_proxy, xml, convert_type (priv->type), &path, &error)) {
+		UNLOCK_CONN ();
 		g_free (xml);
 		g_warning ("Cannot get cal from factory: %s", error ? error->message : "Unknown error");
 		g_error_free (error);
@@ -756,6 +782,8 @@ e_cal_new (ESource *source, ECalSourceType type)
 									"org.gnome.evolution.dataserver.calendar.Cal",
 									&error);
 
+	UNLOCK_CONN ();
+
 	if (!priv->proxy)
 		return NULL;
 
@@ -1021,7 +1049,9 @@ async_signal_idle_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
 		status = get_status_from_error (error);
 	} else {
 		status = E_CALENDAR_STATUS_OK;
+		LOCK_CONN ();
 		org_gnome_evolution_dataserver_calendar_Cal_is_read_only (ecal->priv->proxy, NULL);
+		UNLOCK_CONN ();
 	}
 
 	g_signal_emit (G_OBJECT (ecal), e_cal_signals[CAL_OPENED], 0, status);
@@ -1105,11 +1135,15 @@ open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarSta
 
 	*status = E_CALENDAR_STATUS_OK;
 	if (!async) {
+		LOCK_CONN ();
 		if (!org_gnome_evolution_dataserver_calendar_Cal_open (priv->proxy, only_if_exists, username ? username : "", password ? password : "", error))
 			*status = E_CALENDAR_STATUS_CORBA_EXCEPTION;
+		UNLOCK_CONN ();
 	} else {
+		LOCK_CONN ();
 		if (!org_gnome_evolution_dataserver_calendar_Cal_open_async (priv->proxy, only_if_exists, username ? username : "", password ? password : "", async_signal_idle_cb, ecal))
 			*status = E_CALENDAR_STATUS_CORBA_EXCEPTION;
+		UNLOCK_CONN ();
 	}
 
 	g_free (password);
@@ -1119,8 +1153,11 @@ open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarSta
 		GError *error = NULL;
 		priv->load_state = E_CAL_LOAD_LOADED;
 
-		if (!async)
+		if (!async) {
+			LOCK_CONN ();
 			org_gnome_evolution_dataserver_calendar_Cal_is_read_only (priv->proxy, &error);
+			UNLOCK_CONN ();
+		}
 	} else {
 		priv->load_state = E_CAL_LOAD_NOT_LOADED;
 	}
@@ -1216,9 +1253,12 @@ e_cal_remove (ECal *ecal, GError **error)
 
 	priv = ecal->priv;
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_remove (priv->proxy, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	return TRUE;
 }
@@ -1455,9 +1495,12 @@ e_cal_get_cal_address (ECal *ecal, gchar **cal_address, GError **error)
 			E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 		}
 
+		LOCK_CONN ();
 		if (!org_gnome_evolution_dataserver_calendar_Cal_get_cal_address (priv->proxy, cal_address, error)) {
+			UNLOCK_CONN ();
 			E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 		}
+		UNLOCK_CONN ();
 	} else {
 		*cal_address = g_strdup (priv->cal_address);
 	}
@@ -1492,9 +1535,12 @@ e_cal_get_alarm_email_address (ECal *ecal, gchar **alarm_address, GError **error
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_alarm_email_address (priv->proxy, alarm_address, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	return TRUE;
 }
@@ -1526,9 +1572,12 @@ e_cal_get_ldap_attribute (ECal *ecal, gchar **ldap_attribute, GError **error)
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_ldap_attribute (priv->proxy, ldap_attribute, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	return TRUE;
 }
@@ -1547,9 +1596,12 @@ load_static_capabilities (ECal *ecal, GError **error)
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_scheduling_information (priv->proxy, &priv->capabilities, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	return TRUE;
 }
@@ -1697,11 +1749,14 @@ e_cal_set_mode (ECal *ecal, CalMode mode)
 	priv = ecal->priv;
 	g_return_val_if_fail (priv->load_state == E_CAL_LOAD_LOADED, FALSE);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_set_mode (priv->proxy, mode, &error)) {
+		UNLOCK_CONN ();
 		g_printerr ("%s: %s\n", G_STRFUNC, error ? error->message : "Unknown error");
 		g_error_free (error);
 		return FALSE;
 	}
+	UNLOCK_CONN ();
 
 	return TRUE;
 }
@@ -1746,9 +1801,12 @@ e_cal_get_default_object (ECal *ecal, icalcomponent **icalcomp, GError **error)
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_default_object (priv->proxy, &object, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	if (object) {
 		*icalcomp = icalparser_parse_string (object);
@@ -1797,9 +1855,12 @@ e_cal_get_attachments_for_comp (ECal *ecal, const gchar *uid, const gchar *rid,
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_attachment_list (priv->proxy, uid, rid ? rid: "", &list_array, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	if (list_array) {
 		gchar **string;
@@ -1847,9 +1908,12 @@ e_cal_get_object (ECal *ecal, const gchar *uid, const gchar *rid, icalcomponent
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_object (priv->proxy, uid, rid ? rid : "", &object, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	status = E_CALENDAR_STATUS_OK;
 	tmp_icalcomp = icalparser_parse_string (object);
@@ -1924,9 +1988,12 @@ e_cal_get_objects_for_uid (ECal *ecal, const gchar *uid, GList **objects, GError
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_object (priv->proxy, uid, "", &object, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	status = E_CALENDAR_STATUS_OK;
 	{
@@ -2040,9 +2107,12 @@ e_cal_get_changes (ECal *ecal, const gchar *change_id, GList **changes, GError *
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_changes (priv->proxy, change_id, &additions, &modifications, &removals, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	/* TODO: Be more elegant and split this into a function */
 	/* Mostly copied from the old e-cal-listener.c */
@@ -2148,9 +2218,12 @@ e_cal_get_object_list (ECal *ecal, const gchar *query, GList **objects, GError *
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_object_list (priv->proxy, query, &object_array, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	if (object_array) {
 		icalcomponent *comp;
@@ -2296,10 +2369,13 @@ e_cal_get_free_busy (ECal *ecal, GList *users, time_t start, time_t end,
 	for (l = users, i = 0; l; l = l->next, i++)
 		users_list[i] = g_strdup (l->data);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_free_busy (priv->proxy, (const gchar **)users_list, start, end, &freebusy_array, error)) {
+		UNLOCK_CONN ();
 		g_strfreev (users_list);
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 	g_strfreev (users_list);
 
 	if (freebusy_array) {
@@ -3026,9 +3102,12 @@ e_cal_discard_alarm (ECal *ecal, ECalComponent *comp, const gchar *auid, GError
 
 	e_cal_component_get_uid (comp, &uid);
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_discard_alarm (priv->proxy, uid, auid, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 }
@@ -3227,10 +3306,13 @@ e_cal_create_object (ECal *ecal, icalcomponent *icalcomp, gchar **uid, GError **
 	}
 
 	obj = icalcomponent_as_ical_string_r (icalcomp);
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_create_object (priv->proxy, obj, &muid, error)) {
+		UNLOCK_CONN ();
 		g_free (obj);
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	g_free (obj);
 
@@ -3281,10 +3363,13 @@ e_cal_modify_object (ECal *ecal, icalcomponent *icalcomp, CalObjModType mod, GEr
 	}
 
 	obj = icalcomponent_as_ical_string_r (icalcomp);
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_modify_object (priv->proxy, obj, mod, error)) {
+		UNLOCK_CONN ();
 		g_free (obj);
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	g_free (obj);
 	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
@@ -3324,9 +3409,12 @@ e_cal_remove_object_with_mod (ECal *ecal, const gchar *uid,
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_remove_object (priv->proxy, uid, rid ? rid : "", mod, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 }
@@ -3377,9 +3465,12 @@ e_cal_receive_objects (ECal *ecal, icalcomponent *icalcomp, GError **error)
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_receive_objects (priv->proxy, icalcomponent_as_ical_string (icalcomp), error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 }
@@ -3419,9 +3510,12 @@ e_cal_send_objects (ECal *ecal, icalcomponent *icalcomp, GList **users, icalcomp
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_send_objects (priv->proxy, icalcomponent_as_ical_string (icalcomp), &users_array, &object, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	status = E_CALENDAR_STATUS_OK;
 	if (users_array) {
@@ -3498,9 +3592,13 @@ e_cal_get_timezone (ECal *ecal, const gchar *tzid, icaltimezone **zone, GError *
 	systzid = e_cal_match_tzid (tzid);
 	if (!systzid) {
 		/* call the backend */
+		LOCK_CONN ();
 		if (!org_gnome_evolution_dataserver_calendar_Cal_get_timezone (priv->proxy, tzid, &object, error)) {
+			UNLOCK_CONN ();
 			E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 		}
+		UNLOCK_CONN ();
+
 		icalcomp = icalparser_parse_string (object);
 		if (!icalcomp)
 			status = E_CALENDAR_STATUS_INVALID_OBJECT;
@@ -3592,10 +3690,13 @@ e_cal_add_timezone (ECal *ecal, icaltimezone *izone, GError **error)
 	tzobj = icalcomponent_as_ical_string_r (icalcomp);
 
 	/* call the backend */
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_add_timezone (priv->proxy, tzobj, error)) {
+		UNLOCK_CONN ();
 		g_free (tzobj);
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	g_free (tzobj);
 	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
@@ -3632,21 +3733,26 @@ e_cal_get_query (ECal *ecal, const gchar *sexp, ECalView **query, GError **error
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
 	}
 
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_get_query (priv->proxy, sexp, &query_path, error)) {
+		UNLOCK_CONN ();
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	status = E_CALENDAR_STATUS_OK;
-/*	g_warning ("%s: %s", G_STRLOC, query_path);*/
+
+	LOCK_CONN ();
 	query_proxy = dbus_g_proxy_new_for_name_owner (connection,
                                                 "org.gnome.evolution.dataserver.Calendar", query_path,
                                                 "org.gnome.evolution.dataserver.calendar.CalView", error);
+	UNLOCK_CONN ();
 
 	if (!query_proxy) {
 		*query = NULL;
 		status = E_CALENDAR_STATUS_OTHER_ERROR;
 	} else {
-		*query = e_cal_view_new (query_proxy, ecal);
+		*query = _e_cal_view_new (ecal, query_proxy, &connection_lock);
 	}
 
 	g_object_unref (query_proxy);
@@ -3695,10 +3801,13 @@ e_cal_set_default_timezone (ECal *ecal, icaltimezone *zone, GError **error)
 	tzobj = icalcomponent_as_ical_string_r (icalcomp);
 
 	/* call the backend */
+	LOCK_CONN ();
 	if (!org_gnome_evolution_dataserver_calendar_Cal_set_default_timezone (priv->proxy, tzobj, error)) {
+		UNLOCK_CONN ();
 		g_free (tzobj);
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
 	}
+	UNLOCK_CONN ();
 
 	g_free (tzobj);
 	priv->default_zone = zone;



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