[evolution-data-server] CamelIMAPXConnManager: Give ConnectionInfo a reference count.



commit 8f9ecc77330bff0015758c120f254b3007ef92ba
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Jan 23 10:25:01 2012 -0500

    CamelIMAPXConnManager: Give ConnectionInfo a reference count.
    
    Add lifecycle functions for it:
    
       ConnectionInfo *  connection_info_new    (CamelIMAPXServer *is)
       ConnectionInfo *  connection_info_ref    (ConnectionInfo *cinfo)
       void              connection_info_unref  (ConnectionInfo *cinfo)
    
    Now we can perform list operations without holding CON_LOCK for so long.

 camel/providers/imapx/camel-imapx-conn-manager.c |   63 +++++++++++++++++-----
 1 files changed, 49 insertions(+), 14 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c b/camel/providers/imapx/camel-imapx-conn-manager.c
index 429c018..d15e0d8 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -46,6 +46,7 @@ struct _ConnectionInfo {
 	GHashTable *folders;
 	CamelIMAPXServer *is;
 	gchar *selected_folder;
+	volatile gint ref_count;
 };
 
 enum {
@@ -58,20 +59,52 @@ G_DEFINE_TYPE (
 	camel_imapx_conn_manager,
 	CAMEL_TYPE_OBJECT)
 
+static ConnectionInfo *
+connection_info_new (CamelIMAPXServer *is)
+{
+	ConnectionInfo *cinfo;
+	GHashTable *folders;
+
+	folders = g_hash_table_new_full (
+		(GHashFunc) g_str_hash,
+		(GEqualFunc) g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) NULL);
+
+	cinfo = g_slice_new0 (ConnectionInfo);
+	cinfo->folders = folders;
+	cinfo->is = g_object_ref (is);
+	cinfo->ref_count = 1;
+
+	return cinfo;
+}
+
+static ConnectionInfo *
+connection_info_ref (ConnectionInfo *cinfo)
+{
+	g_return_val_if_fail (cinfo != NULL, NULL);
+	g_return_val_if_fail (cinfo->ref_count > 0, NULL);
+
+	g_atomic_int_inc (&cinfo->ref_count);
+
+	return cinfo;
+}
+
 static void
-free_connection (gpointer data,
-                 gpointer user_data)
+connection_info_unref (ConnectionInfo *cinfo)
 {
-	ConnectionInfo *cinfo = (ConnectionInfo *) data;
-	CamelIMAPXServer *is = cinfo->is;
+	g_return_if_fail (cinfo != NULL);
+	g_return_if_fail (cinfo->ref_count > 0);
 
-	camel_imapx_server_connect (is, NULL, NULL);
+	if (g_atomic_int_dec_and_test (&cinfo->ref_count)) {
+		camel_imapx_server_connect (cinfo->is, NULL, NULL);
 
-	g_object_unref (is);
-	g_hash_table_destroy (cinfo->folders);
-	g_free (cinfo->selected_folder);
+		g_object_unref (cinfo->is);
+		g_hash_table_destroy (cinfo->folders);
+		g_free (cinfo->selected_folder);
 
-	g_free (cinfo);
+		g_slice_free (ConnectionInfo, cinfo);
+	}
 }
 
 static void
@@ -80,7 +113,9 @@ imapx_prune_connections (CamelIMAPXConnManager *con_man)
 	CON_LOCK (con_man);
 
 	con_man->priv->clearing_connections = TRUE;
-	g_list_foreach (con_man->priv->connections, (GFunc) free_connection, NULL);
+	g_list_free_full (
+		con_man->priv->connections,
+		(GDestroyNotify) connection_info_unref);
 	con_man->priv->connections = NULL;
 	con_man->priv->clearing_connections = FALSE;
 
@@ -235,7 +270,7 @@ imapx_conn_shutdown (CamelIMAPXServer *is,
 
 	if (found) {
 		con_man->priv->connections = g_list_remove (con_man->priv->connections, cinfo);
-		free_connection (cinfo, GINT_TO_POINTER (1));
+		connection_info_unref (cinfo);
 	}
 
 	CON_UNLOCK (con_man);
@@ -406,9 +441,9 @@ imapx_create_new_connection (CamelIMAPXConnManager *con_man,
 
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	cinfo = g_new0 (ConnectionInfo, 1);
-	cinfo->is = is;
-	cinfo->folders = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
+	cinfo = connection_info_new (is);
+
+	g_object_unref (is);
 
 	if (folder_name)
 		g_hash_table_insert (cinfo->folders, g_strdup (folder_name), GINT_TO_POINTER (1));



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