evolution r36519 - branches/gnome-2-24/plugins/bbdb



Author: mcrha
Date: Wed Oct  1 08:26:42 2008
New Revision: 36519
URL: http://svn.gnome.org/viewvc/evolution?rev=36519&view=rev

Log:
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.



Modified:
   branches/gnome-2-24/plugins/bbdb/ChangeLog
   branches/gnome-2-24/plugins/bbdb/bbdb.c

Modified: branches/gnome-2-24/plugins/bbdb/bbdb.c
==============================================================================
--- branches/gnome-2-24/plugins/bbdb/bbdb.c	(original)
+++ branches/gnome-2-24/plugins/bbdb/bbdb.c	Wed Oct  1 08:26:42 2008
@@ -132,33 +132,120 @@
 	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 @@
 			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 @@
 			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



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