[evolution-kolab/ek-wip-porting-imapx: 2/7] CamelIMAPXExtdConnManager: adapted to upstream changes
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting-imapx: 2/7] CamelIMAPXExtdConnManager: adapted to upstream changes
- Date: Fri, 3 Feb 2012 15:55:58 +0000 (UTC)
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]