summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2009-01-15 15:15:27 +0000
committerMilan Crha <mcrha@src.gnome.org>2009-01-15 15:15:27 +0000
commitcd4425d370416fbfe146267adc80355b4f720b15 (patch)
treeea9dfb28aacee478ff726dbbc98e0cd8c74dea0d
parent9702dceece1f4152d2946ec623d6a42272428fef (diff)
downloadevolution-data-server-cd4425d370416fbfe146267adc80355b4f720b15.tar.gz
** Fix for bug #501298
2009-01-15 Milan Crha <mcrha@redhat.com> ** Fix for bug #501298 * backends/contacts/e-cal-backend-contacts.c: (struct _ECalBackendContactsPrivate), (init_sources_cb), (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. * backends/contacts/e-cal-backend-contacts.c: (book_record_new), (add_source): Do not search a book when it wasn't opened correctly. * backends/contacts/e-cal-backend-contacts.c: (contact_record_new), (contact_record_free), (contact_record_cb_new): Do not ref/unref backend in a structure which backend holds itself. svn path=/branches/gnome-2-24/; revision=9938
-rw-r--r--calendar/ChangeLog16
-rw-r--r--calendar/backends/contacts/e-cal-backend-contacts.c75
2 files changed, 76 insertions, 15 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 527c575a6..6aef812b9 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,19 @@
+2009-01-15 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #501298
+
+ * backends/contacts/e-cal-backend-contacts.c:
+ (struct _ECalBackendContactsPrivate), (init_sources_cb),
+ (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.
+ * backends/contacts/e-cal-backend-contacts.c: (book_record_new),
+ (add_source): Do not search a book when it wasn't opened correctly.
+ * backends/contacts/e-cal-backend-contacts.c: (contact_record_new),
+ (contact_record_free), (contact_record_cb_new): Do not ref/unref
+ backend in a structure which backend holds itself.
+
2008-12-08 Ian Weisser <ian@korinthianviolins.com>
** Fix for bug #451734
diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c
index e2a263910..405f91652 100644
--- a/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -32,6 +32,7 @@
#include <glib/gi18n-lib.h>
#include "libedataserver/e-xml-hash-utils.h"
+#include "libedataserver/e-flag.h"
#include <libecal/e-cal-recur.h>
#include <libecal/e-cal-util.h>
#include <libedata-cal/e-cal-backend-util.h>
@@ -55,6 +56,8 @@ struct _ECalBackendContactsPrivate {
GHashTable *zones;
icaltimezone *default_zone;
+
+ EFlag *init_done_flag; /* is set, when the init thread gone */
};
typedef struct _BookRecord {
@@ -91,9 +94,17 @@ book_record_new (ECalBackendContacts *cbc, ESource *source)
EBookQuery *query;
EBookView *book_view;
BookRecord *br;
+ GError *error = NULL;
book = e_book_new (source, NULL);
- e_book_open (book, TRUE, NULL);
+ if (!book || !e_book_open (book, TRUE, &error) || error) {
+ g_object_unref (book);
+ if (error) {
+ g_warning ("%s: Failed to open book, error: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ return NULL;
+ }
/* Create book view */
fields = g_list_append (fields, (char*)e_contact_field_name (E_CONTACT_FILE_AS));
@@ -142,7 +153,7 @@ contact_record_new (ECalBackendContacts *cbc, EContact *contact)
ContactRecord *cr = g_new0 (ContactRecord, 1);
char *comp_str;
- cr->cbc = g_object_ref (cbc);
+ cr->cbc = cbc;
cr->contact = contact;
cr->comp_birthday = create_birthday (cbc, contact);
cr->comp_anniversary = create_anniversary (cbc, contact);
@@ -198,7 +209,6 @@ contact_record_free (ContactRecord *cr)
g_object_unref (G_OBJECT (cr->comp_anniversary));
}
- g_object_unref (cr->cbc);
g_free (cr);
}
@@ -214,7 +224,7 @@ contact_record_cb_new (ECalBackendContacts *cbc, ECalBackendSExp *sexp)
{
ContactRecordCB *cb_data = g_new (ContactRecordCB, 1);
- cb_data->cbc = g_object_ref (cbc);
+ cb_data->cbc = cbc;
cb_data->sexp = sexp;
cb_data->result = NULL;
@@ -254,6 +264,9 @@ add_source (ECalBackendContacts *cbc, ESource *source)
BookRecord *br = book_record_new (cbc, source);
const char *uid = e_source_peek_uid (source);
+ if (!br)
+ return;
+
g_hash_table_insert (cbc->priv->addressbooks, g_strdup (uid), br);
}
@@ -721,6 +734,32 @@ e_cal_backend_contacts_is_read_only (ECalBackendSync *backend, EDataCal *cal,
return GNOME_Evolution_Calendar_Success;
}
+static gpointer
+init_sources_cb (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);
+
+ e_flag_set (priv->init_done_flag);
+
+ return NULL;
+}
+
static ECalBackendSyncStatus
e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
gboolean only_if_exists,
@@ -728,8 +767,7 @@ e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
{
ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
ECalBackendContactsPrivate *priv = cbc->priv;
-
- GSList *i;
+ GError *error = NULL;
if (priv->addressbook_loaded)
return GNOME_Evolution_Calendar_Success;
@@ -743,18 +781,18 @@ e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
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);
- }
+ /* initialize addressbook sources in new thread to make this function quick as much as possible */
+ if (!g_thread_create ((GThreadFunc)init_sources_cb, cbc, FALSE, &error)) {
+ e_flag_set (priv->init_done_flag);
+ g_warning ("%s: Cannot create thread to initialize sources! (%s)", G_STRFUNC, error ? error->message : "Unknown error");
+ if (error)
+ g_error_free (error);
- /* 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);
+ return GNOME_Evolution_Calendar_OtherError;
+ }
priv->addressbook_loaded = TRUE;
+
return GNOME_Evolution_Calendar_Success;
}
@@ -948,6 +986,12 @@ e_cal_backend_contacts_finalize (GObject *object)
cbc = E_CAL_BACKEND_CONTACTS (object);
priv = cbc->priv;
+ if (priv->init_done_flag) {
+ e_flag_wait (priv->init_done_flag);
+ e_flag_free (priv->init_done_flag);
+ priv->init_done_flag = NULL;
+ }
+
if (priv->default_zone && priv->default_zone != icaltimezone_get_utc_timezone ()) {
icaltimezone_free (priv->default_zone, 1);
}
@@ -982,6 +1026,7 @@ e_cal_backend_contacts_init (ECalBackendContacts *cbc, ECalBackendContactsClass
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_done_flag = e_flag_new ();
cbc->priv = priv;