Index: calendar/ChangeLog
===================================================================
--- calendar/ChangeLog	(revision 9511)
+++ calendar/ChangeLog	(working copy)
@@ -1,3 +1,16 @@
+2008-09-10  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #501298
+
+	* backends/contacts/e-cal-backend-contacts.c:
+	(struct _ECalBackendContactsPrivate), (init_sources_on_idle),
+	(e_cal_backend_contacts_open), (e_cal_backend_contacts_finalize),
+	(e_cal_backend_contacts_init): Make _open function quick as much
+	as possible, to not block the sync_backend lock for long, thus other
+	threads can work with it too.
+	* libecal/e-cal.c: (cal_read_only_cb): Do not claim on this event when
+	there is no operation, it could come async.
+
 2008-09-05  Andre Klapper  <a9016009@gmx.de>
 
 	* libedata-cal/e-cal-backend-util.c: 
Index: calendar/backends/contacts/e-cal-backend-contacts.c
===================================================================
--- calendar/backends/contacts/e-cal-backend-contacts.c	(revision 9511)
+++ calendar/backends/contacts/e-cal-backend-contacts.c	(working copy)
@@ -55,6 +55,8 @@ struct _ECalBackendContactsPrivate {
 
 	GHashTable *zones;
 	icaltimezone *default_zone;
+
+	guint init_sources_id;
 };
 
 typedef struct _BookRecord {
@@ -721,6 +723,32 @@ e_cal_backend_contacts_is_read_only (ECa
 	return GNOME_Evolution_Calendar_Success;
 }
 
+static gboolean
+init_sources_on_idle (ECalBackendContacts *cbc)
+{
+        ECalBackendContactsPrivate *priv;
+        GSList *i;
+
+	g_return_val_if_fail (cbc != NULL, FALSE);
+
+	priv = cbc->priv;
+
+	/* Create address books for existing sources */
+        for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next) {
+                ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
+
+                source_group_added_cb (priv->addressbook_sources, source_group, cbc);
+        }
+
+        /* Listen for source list changes */
+        g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
+        g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
+
+	priv->init_sources_id = 0;
+
+	return FALSE;
+}
+
 static ECalBackendSyncStatus
 e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
 			     gboolean only_if_exists,
@@ -729,8 +757,6 @@ e_cal_backend_contacts_open (ECalBackend
         ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
         ECalBackendContactsPrivate *priv = cbc->priv;
 
-        GSList *i;
-
         if (priv->addressbook_loaded)
                 return GNOME_Evolution_Calendar_Success;
 
@@ -743,18 +769,9 @@ e_cal_backend_contacts_open (ECalBackend
 		g_hash_table_insert (priv->zones, g_strdup (icaltimezone_get_tzid (zone)), zone);
 	}
 
-	/* Create address books for existing sources */
-        for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next) {
-                ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
-
-                source_group_added_cb (priv->addressbook_sources, source_group, cbc);
-        }
-
-        /* Listen for source list changes */
-        g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
-        g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
-
+	priv->init_sources_id = g_idle_add ((GSourceFunc)init_sources_on_idle, cbc);
         priv->addressbook_loaded = TRUE;
+
         return GNOME_Evolution_Calendar_Success;
 }
 
@@ -948,6 +965,11 @@ e_cal_backend_contacts_finalize (GObject
 	cbc = E_CAL_BACKEND_CONTACTS (object);
 	priv = cbc->priv;
 
+	if (priv->init_sources_id) {
+		g_source_remove (priv->init_sources_id);
+		priv->init_sources_id = 0;
+	}
+
 	if (priv->default_zone && priv->default_zone != icaltimezone_get_utc_timezone ()) {
 		icaltimezone_free (priv->default_zone, 1);
 	}
@@ -982,6 +1004,7 @@ e_cal_backend_contacts_init (ECalBackend
 
 	priv->zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_zone);
 	priv->default_zone = icaltimezone_get_utc_timezone ();
+	priv->init_sources_id = 0;
 
 	cbc->priv = priv;
 
Index: calendar/libecal/e-cal.c
===================================================================
--- calendar/libecal/e-cal.c	(revision 9511)
+++ calendar/libecal/e-cal.c	(working copy)
@@ -437,7 +437,11 @@ cal_read_only_cb (ECalListener *listener
 	ECal *ecal = data;
 	ECalendarOp *op;
 
-	op = e_calendar_get_op (ecal);
+	/* readonly information comes asynchronously, possibly without operation */
+	if (ecal->priv->current_op)
+		op = e_calendar_get_op (ecal);
+	else
+		op = NULL;
 
 	if (op == NULL || !op->bool) {
 		ecal->priv->read_only = read_only;
