Patch: fix some camel operation and camel queue leaks



	Hi,

	This patch fixes some leak references (and improves a bit other
references usage), mainly related to camel operation and camel queue.

	We also make the reference from tny camel queue to account be weak, so
that the queue thread can be freed.

Changelog would be:
* libtinymail-camel/tny-camel-folder.c:
        * Fix camel operation references
* libtinymail-camel/tny-camel-bs-mime-part.c:
        * Fix camel operation references
* libtinymail-camel/tny-camel-queue.c:
        * Make queue reference to account be weak.
* libtinymail-camel/tny-camel-account.c:
        * More camel operation reference fixes.

-- 
José Dapena Paz <jdapena igalia com>
Igalia
Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c	(revision 3702)
+++ libtinymail-camel/tny-camel-folder.c	(working copy)
@@ -2508,13 +2508,13 @@
 	if (priv->account && TNY_IS_CAMEL_ACCOUNT (priv->account)) {
 		TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account);
 		apriv->getmsg_cancel = cancel;
+		camel_operation_ref (cancel);
 	}
 
 	/* To disable parallel getting of messages while summary is being retreived,
 	 * restore this lock (A) */
 	/* g_static_rec_mutex_lock (priv->folder_lock); */
 
-	camel_operation_ref (cancel);
 	camel_operation_register (cancel);
 	camel_operation_start (cancel, (char *) "Getting message");
 
@@ -2535,6 +2535,7 @@
 	if (priv->account && TNY_IS_CAMEL_ACCOUNT (priv->account)) {
 		TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account);
 		apriv->getmsg_cancel = NULL;
+		camel_operation_unref (cancel);
 	}
 
 	/* To disable parallel getting of messages while summary is being retreived,
Index: libtinymail-camel/tny-camel-bs-mime-part.c
===================================================================
--- libtinymail-camel/tny-camel-bs-mime-part.c	(revision 3702)
+++ libtinymail-camel/tny-camel-bs-mime-part.c	(working copy)
@@ -556,11 +556,11 @@
 		TnyCamelFolderPriv *fpriv = TNY_CAMEL_FOLDER_GET_PRIVATE (priv->folder);
 		if (fpriv->account && TNY_IS_CAMEL_ACCOUNT (fpriv->account)) {
 			TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (fpriv->account);
+			camel_operation_ref (cancel);
 			apriv->getmsg_cancel = cancel;
 		}
 	}
 
-	camel_operation_ref (cancel);
 	camel_operation_register (cancel);
 	camel_operation_start (cancel, (char *) "Getting message part");
 
@@ -588,6 +588,7 @@
 		if (fpriv->account && TNY_IS_CAMEL_ACCOUNT (fpriv->account)) {
 			TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (fpriv->account);
 			apriv->getmsg_cancel = NULL;
+			camel_operation_unref (cancel);
 		}
 	}
 
Index: libtinymail-camel/tny-camel-queue.c
===================================================================
--- libtinymail-camel/tny-camel-queue.c	(revision 3702)
+++ libtinymail-camel/tny-camel-queue.c	(working copy)
@@ -39,6 +39,7 @@
 #define TNY_CAMEL_QUEUE_GET_PRIVATE(o)	\
 	(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_CAMEL_QUEUE, TnyCamelQueuePriv))
 
+static void account_finalized (TnyCamelQueue *queue, GObject *finalized_account);
 
 static void
 tny_camel_queue_finalize (GObject *object)
@@ -47,6 +48,11 @@
 
 	self->stopped = TRUE;
 
+	g_mutex_lock (self->mutex);
+	if (self->account)
+		g_object_weak_unref (G_OBJECT (self->account), (GWeakNotify) account_finalized, self);
+	g_mutex_unlock (self->mutex);
+
 	g_static_rec_mutex_lock (self->lock);
 	g_list_free (self->list);
 	self->list = NULL;
@@ -64,6 +70,18 @@
 	return;
 }
 
+static void
+account_finalized (TnyCamelQueue *queue, GObject *finalized_account)
+{
+	g_mutex_lock (queue->mutex);
+	queue->account = NULL;
+	queue->stopped = TRUE;
+	if (queue->is_waiting) {
+		g_cond_broadcast (queue->condition);
+	}
+	g_mutex_unlock (queue->mutex);
+}
+
 /**
  * _tny_camel_queue_new
  * @account: the account
@@ -78,6 +96,7 @@
 	TnyCamelQueue *self = g_object_new (TNY_TYPE_CAMEL_QUEUE, NULL);
 
 	self->account = account;
+	g_object_weak_ref (G_OBJECT (account), (GWeakNotify) account_finalized, self);
 
 	return TNY_CAMEL_QUEUE (self);
 }
@@ -175,7 +194,15 @@
 
 		if (queue->next_uncancel)
 		{
-			_tny_camel_account_actual_uncancel (TNY_CAMEL_ACCOUNT (queue->account));
+			g_mutex_lock (queue->mutex);
+			if (queue->account) {
+				g_object_ref (queue->account);
+				g_mutex_unlock (queue->mutex);
+				_tny_camel_account_actual_uncancel (TNY_CAMEL_ACCOUNT (queue->account));
+				g_object_unref (queue->account);
+			} else {
+				g_mutex_unlock (queue->mutex);
+			}
 			queue->next_uncancel = FALSE;
 		}
 
@@ -255,7 +282,6 @@
 	queue->thread = NULL;
 	queue->stopped = TRUE;
 
-	g_object_unref (queue->account);
 	g_object_unref (queue);
 
 	return NULL;
@@ -334,7 +360,8 @@
 	if (item) {
 		if (item->flags & TNY_CAMEL_QUEUE_CANCELLABLE_ITEM) {
 			if (!(item->flags & TNY_CAMEL_QUEUE_SYNC_ITEM)) {
-				_tny_camel_account_actual_cancel (TNY_CAMEL_ACCOUNT (queue->account));
+				if (queue->account)
+					_tny_camel_account_actual_cancel (TNY_CAMEL_ACCOUNT (queue->account));
 				queue->next_uncancel = TRUE;
 			}
 		}
@@ -388,6 +415,9 @@
 
 	g_static_rec_mutex_lock (queue->lock);
 
+	if (queue->account == NULL)
+		g_assert ("We should never be running tny_camel_queue_launch_wflags if account was unreferenced");
+
 	if (flags & TNY_CAMEL_QUEUE_PRIORITY_ITEM) 
 	{
 		/* Preserve the order for prioritized items */
@@ -412,7 +442,6 @@
 		GError *err = NULL;
 		queue->stopped = FALSE;
 		g_object_ref (queue);
-		g_object_ref (queue->account);
 		queue->thread = g_thread_create (tny_camel_queue_thread_main_func, 
 			queue, FALSE, &err);
 		if (err) {
Index: libtinymail-camel/tny-camel-account.c
===================================================================
--- libtinymail-camel/tny-camel-account.c	(revision 3702)
+++ libtinymail-camel/tny-camel-account.c	(working copy)
@@ -774,13 +774,13 @@
 
 	priv->inuse_spin = TRUE;
 
-	if (priv->cancel)
+	if (priv->cancel) {
 		_tny_camel_account_actual_uncancel (self);
+		camel_operation_unregister (priv->cancel);
+	}
 
 	priv->cancel = camel_operation_new (func, user_data);
 
-	camel_operation_ref (priv->cancel);
-	camel_operation_register (priv->cancel);
 	camel_operation_start (priv->cancel, (char*)what);
 
 	g_static_rec_mutex_unlock (priv->cancel_lock);


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