[evolution-data-server] IMAP: Split off a new mutex for commands and responses.



commit 78eb998057d86fb526361269d9d09ed2173bc98e
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Oct 25 17:19:39 2011 -0400

    IMAP: Split off a new mutex for commands and responses.
    
    Define a new public GStaticRecMutex named "command_and_response_lock"
    on CamelImapStore for IMAP command and response operations to use.
    
    Fixes some deadlocks I was encountering due to the overreliance on
    CAMEL_SERVICE_REC_CONNECT_LOCK, particularly during authentication.

 camel/providers/imap/camel-imap-command.c |   21 ++++++++++-----------
 camel/providers/imap/camel-imap-store.c   |    4 ++++
 camel/providers/imap/camel-imap-store.h   |    3 +++
 3 files changed, 17 insertions(+), 11 deletions(-)
---
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
index 03d1506..7ed6061 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -94,7 +94,7 @@ camel_imap_command (CamelImapStore *store,
 	va_list ap;
 	gchar *cmd;
 
-	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	g_static_rec_mutex_lock (&store->command_and_response_lock);
 
 	if (fmt) {
 		va_start (ap, fmt);
@@ -114,7 +114,7 @@ camel_imap_command (CamelImapStore *store,
 
 	if (!imap_command_start (store, folder, cmd, cancellable, error)) {
 		g_free (cmd);
-		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		g_static_rec_mutex_unlock (&store->command_and_response_lock);
 		return NULL;
 	}
 	g_free (cmd);
@@ -172,12 +172,13 @@ camel_imap_command_start (CamelImapStore *store,
 	cmd = imap_command_strdup_vprintf (store, fmt, ap);
 	va_end (ap);
 
-	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	g_static_rec_mutex_lock (&store->command_and_response_lock);
 	ok = imap_command_start (store, folder, cmd, cancellable, error);
 	g_free (cmd);
 
 	if (!ok)
-		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+		g_static_rec_mutex_unlock (&store->command_and_response_lock);
+
 	return ok;
 }
 
@@ -306,9 +307,7 @@ camel_imap_command_continuation (CamelImapStore *store,
 	    camel_stream_write (store->ostream, "\r\n", 2, cancellable, error) == -1) {
 		camel_service_disconnect_sync (
 			CAMEL_SERVICE (store), FALSE, NULL);
-		camel_service_unlock (
-			CAMEL_SERVICE (store),
-			CAMEL_SERVICE_REC_CONNECT_LOCK);
+		g_static_rec_mutex_unlock (&store->command_and_response_lock);
 		return NULL;
 	}
 
@@ -355,7 +354,7 @@ camel_imap_command_response (CamelImapStore *store,
 	user = camel_network_settings_get_user (network_settings);
 
 	if (camel_imap_store_readline (store, &respbuf, cancellable, error) < 0) {
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+		g_static_rec_mutex_unlock (&store->command_and_response_lock);
 		return CAMEL_IMAP_RESPONSE_ERROR;
 	}
 
@@ -418,7 +417,7 @@ camel_imap_command_response (CamelImapStore *store,
 
 	if (type == CAMEL_IMAP_RESPONSE_ERROR ||
 	    type == CAMEL_IMAP_RESPONSE_TAGGED)
-		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+		g_static_rec_mutex_unlock (&store->command_and_response_lock);
 
 	return type;
 }
@@ -437,7 +436,7 @@ imap_read_response (CamelImapStore *store,
 	 * we're still locked. This lock is owned by response
 	 * and gets unlocked when response is freed.
 	 */
-	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	g_static_rec_mutex_lock (&store->command_and_response_lock);
 
 	response = g_new0 (CamelImapResponse, 1);
 /*FIXME	if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
@@ -708,7 +707,7 @@ camel_imap_response_free (CamelImapStore *store,
 	}
 
 	g_free (response);
-	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	g_static_rec_mutex_unlock (&store->command_and_response_lock);
 }
 
 /**
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 6844799..13c561a 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -743,6 +743,8 @@ imap_store_finalize (GObject *object)
 	/* This frees current_folder, folders, authtypes, streams, and namespace. */
 	camel_service_disconnect_sync (CAMEL_SERVICE (imap_store), TRUE, NULL);
 
+	g_static_rec_mutex_free (&imap_store->command_and_response_lock);
+
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object);
 }
@@ -1509,6 +1511,8 @@ camel_subscribable_init (CamelSubscribableInterface *interface)
 static void
 camel_imap_store_init (CamelImapStore *imap_store)
 {
+	g_static_rec_mutex_init (&imap_store->command_and_response_lock);
+
 	imap_store->istream = NULL;
 	imap_store->ostream = NULL;
 
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index 700dd0a..0295860 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -80,6 +80,9 @@ struct _CamelImapStore {
 	CamelOfflineStore parent;
 	CamelImapStorePrivate *priv;
 
+	/* For processing IMAP commands and responses. */
+	GStaticRecMutex command_and_response_lock;
+
 	CamelStream *istream;
 	CamelStream *ostream;
 



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