aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/bbdb/ChangeLog8
-rw-r--r--plugins/bbdb/bbdb.c111
2 files changed, 106 insertions, 13 deletions
diff --git a/plugins/bbdb/ChangeLog b/plugins/bbdb/ChangeLog
index 471a76aa21..f7b0b27e30 100644
--- a/plugins/bbdb/ChangeLog
+++ b/plugins/bbdb/ChangeLog
@@ -1,3 +1,11 @@
+2008-10-01 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #553527
+
+ * bbdb.c: (struct todo_struct), (free_todo_struct), (bbdb_do_in_thread),
+ (bbdb_do_thread), (bbdb_handle_reply): Do the EBook work in a separate
+ thread to have better performance on reply with slow address books.
+
2008-09-29 Milan Crha <mcrha@redhat.com>
** Fix for bug #497928
diff --git a/plugins/bbdb/bbdb.c b/plugins/bbdb/bbdb.c
index a2ec60d243..547a779961 100644
--- a/plugins/bbdb/bbdb.c
+++ b/plugins/bbdb/bbdb.c
@@ -132,33 +132,120 @@ bbdb_timeout (gpointer data)
return TRUE;
}
-/* Code to populate addressbook when you reply to a mail follows */
+typedef struct
+{
+ char *name;
+ char *email;
+} todo_struct;
-void
-bbdb_handle_reply (EPlugin *ep, EMEventTargetMessage *target)
+static void
+free_todo_struct (todo_struct *td)
{
- const CamelInternetAddress *cia;
- EBook *book = NULL;
- int i;
+ if (td) {
+ g_free (td->name);
+ g_free (td->email);
+ g_free (td);
+ }
+}
+
+static GSList *todo = NULL;
+G_LOCK_DEFINE_STATIC (todo);
+
+static gpointer
+bbdb_do_in_thread (gpointer data)
+{
+ EBook *book;
/* Open the addressbook */
book = bbdb_open_addressbook (AUTOMATIC_CONTACTS_ADDRESSBOOK);
- if (book == NULL)
+ if (book == NULL) {
+ G_LOCK (todo);
+
+ g_slist_foreach (todo, (GFunc)free_todo_struct, NULL);
+ g_slist_free (todo);
+ todo = NULL;
+
+ G_UNLOCK (todo);
+ return NULL;
+ }
+
+ G_LOCK (todo);
+ while (todo) {
+ todo_struct *td = todo->data;
+
+ todo = g_slist_remove (todo, td);
+
+ G_UNLOCK (todo);
+
+ if (td) {
+ bbdb_do_it (book, td->name, td->email);
+ free_todo_struct (td);
+ }
+
+ G_LOCK (todo);
+ }
+ G_UNLOCK (todo);
+
+ g_object_unref (book);
+
+ return NULL;
+}
+
+static void
+bbdb_do_thread (const char *name, const char *email)
+{
+ todo_struct *td;
+
+ if (!name && !email)
return;
+ td = g_new (todo_struct, 1);
+ td->name = g_strdup (name);
+ td->email = g_strdup (email);
+
+ G_LOCK (todo);
+ if (todo) {
+ /* the list isn't empty, which means there is a thread taking
+ care of that, thus just add it to the queue */
+ todo = g_slist_append (todo, td);
+ } else {
+ GError *error = NULL;
+
+ /* list was empty, add item and create a thread */
+ todo = g_slist_append (todo, td);
+ g_thread_create (bbdb_do_in_thread, NULL, FALSE, &error);
+
+ if (error) {
+ g_warning ("%s: Creation of the thread failed with error: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+
+ G_UNLOCK (todo);
+ bbdb_do_in_thread (NULL);
+ G_LOCK (todo);
+ }
+ }
+ G_UNLOCK (todo);
+}
+
+/* Code to populate addressbook when you reply to a mail follows */
+void
+bbdb_handle_reply (EPlugin *ep, EMEventTargetMessage *target)
+{
+ const CamelInternetAddress *cia;
+ int i;
+
cia = camel_mime_message_get_from (target->message);
if (cia) {
for (i = 0; i < camel_address_length (CAMEL_ADDRESS (cia)); i ++) {
const char *name=NULL, *email=NULL;
if (!(camel_internet_address_get (cia, i, &name, &email)))
continue;
- bbdb_do_it (book, name, email);
+ bbdb_do_thread (name, email);
}
}
/* If this is a reply-all event, process To: and Cc: also. */
if (((EEventTarget *) target)->mask & EM_EVENT_MESSAGE_REPLY_ALL) {
- g_object_unref (G_OBJECT (book));
return;
}
@@ -168,7 +255,7 @@ bbdb_handle_reply (EPlugin *ep, EMEventTargetMessage *target)
const char *name=NULL, *email=NULL;
if (!(camel_internet_address_get (cia, i, &name, &email)))
continue;
- bbdb_do_it (book, name, email);
+ bbdb_do_thread (name, email);
}
}
@@ -178,11 +265,9 @@ bbdb_handle_reply (EPlugin *ep, EMEventTargetMessage *target)
const char *name=NULL, *email=NULL;
if (!(camel_internet_address_get (cia, i, &name, &email)))
continue;
- bbdb_do_it (book, name, email);
+ bbdb_do_thread (name, email);
}
}
-
- g_object_unref (G_OBJECT (book));
}
static void