[evolution-kolab/ek-wip-porting-imapx: 2/7] CamelIMAPXExtdConnManager: adapted to upstream changes



commit 68d191a7ef5b5b12374232963fba5d014b2ceac0
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri Feb 3 14:46:43 2012 +0100

    CamelIMAPXExtdConnManager: adapted to upstream changes
    
    * removed no-longer needed internal code paths
    * pulled in locking changes from parent class
      as well as fixes / general code changes

 .../imapx/camel-imapx-extd-conn-manager.c          |  260 ++++++--------------
 1 files changed, 72 insertions(+), 188 deletions(-)
---
diff --git a/src/camel/providers/imapx/camel-imapx-extd-conn-manager.c b/src/camel/providers/imapx/camel-imapx-extd-conn-manager.c
index 3eb00e0..fb222df 100644
--- a/src/camel/providers/imapx/camel-imapx-extd-conn-manager.c
+++ b/src/camel/providers/imapx/camel-imapx-extd-conn-manager.c
@@ -40,11 +40,6 @@
 G_DEFINE_TYPE (CamelIMAPXExtdConnManager, camel_imapx_extd_conn_manager, CAMEL_TYPE_IMAPX_CONN_MANAGER)
 
 /*----------------------------------------------------------------------------*/
-/* forward declarations */
-
-static void extd_conn_manager_prune_connections (CamelIMAPXConnManager *self);
-
-/*----------------------------------------------------------------------------*/
 /* object init */
 
 static void
@@ -58,8 +53,6 @@ camel_imapx_extd_conn_manager_dispose (GObject *object)
 {
 	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (object));
 
-	extd_conn_manager_prune_connections (CAMEL_IMAPX_CONN_MANAGER (object));
-
 	G_OBJECT_CLASS (camel_imapx_extd_conn_manager_parent_class)->dispose (object);
 }
 
@@ -75,159 +68,64 @@ camel_imapx_extd_conn_manager_finalize (GObject *object)
 /* local statics */
 
 static void
-extd_conn_manager_free_connection (gpointer data,
-                                   gpointer user_data)
-{
-	/* modified dupe of free_connection() */
-
-	ConnectionInfo *cinfo = (ConnectionInfo *) data;
-	CamelIMAPXExtdServer *eserver = CAMEL_IMAPX_EXTD_SERVER (cinfo->conn);
-
-	/* modified */
-	camel_imapx_extd_server_connect (CAMEL_IMAPX_SERVER (eserver),
-	                                 NULL,
-	                                 NULL);
-
-	g_object_unref (eserver);
-	g_hash_table_destroy (cinfo->folders);
-	g_free (cinfo->selected_folder);
-
-	g_free (cinfo);
-}
-
-static void
-extd_conn_manager_prune_connections (CamelIMAPXConnManager *self)
-{
-	/* modified dupe of imapx_prune_connections */
-
-	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self));
-
-	CON_LOCK (self);
-
-	self->priv->clearing_connections = TRUE;
-	g_list_foreach (self->priv->connections,
-	                /* modified */
-	                (GFunc) extd_conn_manager_free_connection,
-	                NULL);
-	self->priv->connections = NULL;
-	self->priv->clearing_connections = FALSE;
-
-	CON_UNLOCK (self);
-}
-
-/* TODO destroy unused connections in a time-out loop */
-static void
-extd_conn_manager_shutdown (CamelIMAPXConnManager *self,
-                            CamelIMAPXServer *server)
+extd_conn_manager_conn_shutdown (CamelIMAPXServer *is,
+                                 CamelIMAPXConnManager *con_man)
 {
-	/* modified dupe of imapx_conn_shutdown() */
-
-	GList *l = NULL;
-	ConnectionInfo *cinfo = NULL;
-	gboolean found = FALSE;
-
-	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self));
-	g_assert (CAMEL_IS_IMAPX_EXTD_SERVER (server));
-
-	/* when clearing connections then other thread than a parser thread,
-	 * in which this function is called, holds the CON_LOCK, thus skip
-	 * this all, because otherwise a deadlock will happen.
-	 * The connection will be freed later anyway. */
-	if (self->priv->clearing_connections) {
-		c(server->tagprefix, "%s: called on %p when clearing connections, skipping it...\n", G_STRFUNC, server);
-		return;
-	}
-
-	CON_LOCK (self);
-
-	for (l = self->priv->connections; l != NULL; l = g_list_next (l)) {
-		cinfo = (ConnectionInfo *) l->data;
-		if (cinfo->conn == server) {
-			found = TRUE;
-			break;
-		}
-	}
-
-	if (found) {
-		self->priv->connections = g_list_remove (self->priv->connections, cinfo);
-		/* modified */
-		extd_conn_manager_free_connection (cinfo, GINT_TO_POINTER (1));
-	}
+	g_assert (CAMEL_IS_IMAPX_EXTD_SERVER (is));
+	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (con_man));
 
-	CON_UNLOCK (self);
+	camel_imapx_conn_manager_conn_shutdown (is, con_man);
 }
 
 static void
-extd_conn_manager_update_select (CamelIMAPXServer *self,
-                                 const gchar *selected_folder,
-                                 CamelIMAPXConnManager *con_man)
+extd_conn_manager_conn_update_select (CamelIMAPXServer *is,
+                                      const gchar *selected_folder,
+                                      CamelIMAPXConnManager *con_man)
 {
-	GList *l = NULL;
-	ConnectionInfo *cinfo = NULL;
-	gboolean found = FALSE;
-
-	g_assert (CAMEL_IS_IMAPX_EXTD_SERVER (self));
+	g_assert (CAMEL_IS_IMAPX_EXTD_SERVER (is));
 	g_assert (selected_folder != NULL);
 	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (con_man));
 
-	CON_LOCK (con_man);
-
-	for (l = con_man->priv->connections; l != NULL; l = g_list_next (l)) {
-		cinfo = (ConnectionInfo *) l->data;
-		if (cinfo->conn == self) {
-			found = TRUE;
-			break;
-		}
-	}
-
-	if (found) {
-		if (cinfo->selected_folder) {
-			IMAPXJobQueueInfo *jinfo;
-
-			jinfo = camel_imapx_server_get_job_queue_info (cinfo->conn);
-			if (!g_hash_table_lookup (jinfo->folders, cinfo->selected_folder)) {
-				g_hash_table_remove (cinfo->folders, cinfo->selected_folder);
-				c(self->tagprefix, "Removed folder %s from connection folder list - select changed \n", cinfo->selected_folder);
-			}
-			camel_imapx_destroy_job_queue_info (jinfo);
-			g_free (cinfo->selected_folder);
-		}
-
-		cinfo->selected_folder = g_strdup (selected_folder);
-	}
-
-	CON_UNLOCK (con_man);
+	camel_imapx_conn_manager_conn_update_select (is,
+	                                             selected_folder,
+	                                             con_man);
 }
 
-static CamelIMAPXExtdServer*
-extd_conn_manager_create_new_connection (CamelIMAPXConnManager *self,
-                                         const gchar *foldername,
-                                         GCancellable *cancellable,
-                                         GError **err)
+static CamelIMAPXServer*
+extd_conn_manager_new_connection_unlocked (CamelIMAPXConnManager *con_man,
+                                           const gchar *folder_name,
+                                           GCancellable *cancellable,
+                                           GError **error)
 {
-	/* modified dupe of imapx_create_new_connection() */
+	/* modified dupe of imapx_conn_manager_get_connection() */
 
-	CamelIMAPXExtdServer *eserver = NULL;
+	CamelIMAPXExtdServer *es = NULL;
+	CamelIMAPXServer *is = NULL;
 	CamelIMAPXStore *imapx_store = NULL;
-	CamelStore *store = NULL;
+	CamelStore *store = con_man->priv->store;
 	CamelService *service = NULL;
-	ConnectionInfo *cinfo = NULL;
+	struct _ConnectionInfo *cinfo = NULL;
 	gboolean success = FALSE;
 
-	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self));
-	g_assert (foldername != NULL);
+	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (con_man));
+	g_assert (folder_name != NULL);
 	/* cancellable may be NULL */
-	g_return_val_if_fail (err == NULL || *err == NULL, NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	/* Caller must be holding CON_WRITE_LOCK. */
 
-	store = self->priv->store;
 	service = CAMEL_SERVICE (store);
-	imapx_store = CAMEL_IMAPX_STORE (store);
 
-	CON_LOCK (self);
+	imapx_store = CAMEL_IMAPX_STORE (store);
 
 	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	eserver = camel_imapx_extd_server_new (CAMEL_IMAPX_EXTD_STORE (store));
+	/* Check if we got cancelled while we were waiting. */
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		goto exit;
+
+	es = camel_imapx_extd_server_new (CAMEL_IMAPX_EXTD_STORE (store));
+	is = CAMEL_IMAPX_SERVER (es);
 
 	/* XXX As part of the connect operation the CamelIMAPXServer will
 	 *     have to call camel_session_authenticate_sync(), but it has
@@ -241,51 +139,39 @@ extd_conn_manager_create_new_connection (CamelIMAPXConnManager *self,
 	 *     CamelIMAPXServer to act on in its authenticate_sync() method.
 	 *
 	 *     Because we're holding the CAMEL_SERVICE_REC_CONNECT_LOCK
-	 *     (and our own CON_LOCK for that matter) we should not have
-	 *     multiple IMAPX connections trying to authenticate at once,
-	 *     so this should be thread-safe.
+	 *     we should not have multiple IMAPX connections trying to
+	 *     authenticate at once, so this should be thread-safe.
 	 */
-	imapx_store->authenticating_server = g_object_ref (eserver);
-	success = camel_imapx_extd_server_connect (CAMEL_IMAPX_SERVER (eserver),
-	                                           cancellable,
-	                                           err);
+	imapx_store->authenticating_server = g_object_ref (is);
+	success = camel_imapx_extd_server_connect (is, cancellable, error);
 	g_object_unref (imapx_store->authenticating_server);
 	imapx_store->authenticating_server = NULL;
 
-	if (success) {
-		g_object_ref (eserver);
-	} else {
-		g_object_unref (eserver);
-
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-		CON_UNLOCK (self);
-
-		return NULL;
+	if (!success) {
+		g_object_unref (es);
+		is = NULL;
+		goto exit;
 	}
 
-	/* modified */
-	g_signal_connect (eserver, "shutdown", G_CALLBACK (extd_conn_manager_shutdown), self);
-	g_signal_connect (eserver, "select_changed", G_CALLBACK (extd_conn_manager_update_select), self);
-
-	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+	g_signal_connect (es, "shutdown",
+	                  G_CALLBACK (extd_conn_manager_conn_shutdown), con_man);
+	g_signal_connect (es, "select_changed",
+	                  G_CALLBACK (extd_conn_manager_conn_update_select), con_man);
 
-	cinfo = g_new0 (ConnectionInfo, 1);
-	cinfo->conn = CAMEL_IMAPX_SERVER (eserver);
-	cinfo->folders = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
+	cinfo = camel_imapx_conn_manager_connection_info_new (is);
 
-	if (foldername)
-		g_hash_table_insert (cinfo->folders, g_strdup (foldername), GINT_TO_POINTER (1));
+	if (folder_name != NULL)
+		camel_imapx_conn_manager_connection_info_insert_folder_name (cinfo, folder_name);
 
-	self->priv->connections = g_list_prepend (self->priv->connections, cinfo);
+	/* Takes ownership of the ConnectionInfo. */
+	con_man->priv->connections = g_list_prepend (con_man->priv->connections, cinfo);
 
-	c(CAMEL_IMAPX_SERVER (eserver)->tagprefix,
-	  "Created new connection for %s and total connections %d \n",
-	  foldername,
-	  g_list_length (self->priv->connections));
+	c(is->tagprefix, "Created new connection for %s and total connections %d \n", folder_name, g_list_length (con_man->priv->connections));
 
-	CON_UNLOCK (self);
+ exit:
+	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	return eserver;
+	return is;
 }
 
 /*----------------------------------------------------------------------------*/
@@ -312,32 +198,30 @@ imapx_extd_conn_manager_get_connection (CamelIMAPXConnManager *self,
 {
 	/* modified dupe of imapx_conn_manager_get_connection() */
 
-	CamelIMAPXExtdServer *eserver = NULL;
-	CamelIMAPXServer *server = NULL;
+	CamelIMAPXServer *is = NULL;
 
-	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self));
+	g_return_val_if_fail (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self), NULL);
 	g_assert (foldername != NULL);
 	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, NULL);
 
-	CON_LOCK (self);
-
-	/* modified */
-	server = camel_imapx_conn_manager_find_connection_unlocked (self, foldername);
-	if (!server) {
-		/* modified */
-		eserver = extd_conn_manager_create_new_connection (self,
-		                                                   foldername,
-		                                                   cancellable,
-		                                                   err);
+	/* Hold the writer lock while we requisition a CamelIMAPXServer
+	 * to prevent other threads from adding or removing connections. */
+	CON_WRITE_LOCK (self);
+
+	/* Check if we got cancelled while waiting for the lock. */
+	if (!g_cancellable_set_error_if_cancelled (cancellable, err)) {
+		is = camel_imapx_conn_manager_find_connection_unlocked (self, foldername);
+		if (is == NULL)
+			is = extd_conn_manager_new_connection_unlocked (self,
+			                                                foldername,
+			                                                cancellable,
+			                                                err);
 	}
 
-	CON_UNLOCK (self);
+	CON_WRITE_UNLOCK (self);
 
-	if (eserver != NULL)
-		server = CAMEL_IMAPX_SERVER (eserver);
-
-	return server;
+	return is;
 }
 
 static void
@@ -345,7 +229,7 @@ imapx_extd_conn_manager_close_connections (CamelIMAPXConnManager *self)
 {
 	g_assert (CAMEL_IS_IMAPX_EXTD_CONN_MANAGER (self));
 
-	extd_conn_manager_prune_connections (CAMEL_IMAPX_CONN_MANAGER (self));
+	camel_imapx_conn_manager_close_connections (CAMEL_IMAPX_CONN_MANAGER (self));
 }
 
 static GList*



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