Patch: use a separate lock for observers list in merge folder



	Hi,

	This patch maintains a separate lock for observers list in
TnyMergeFolder. This should prevent locks from inner folders interlock
with the merge folder itself on notification calls.

	Another solution would be modifying the structure and architecture of
folders to be able to have a tinymail level api lock:

	tny_folder_get_mutex ()

	We would drop camel folder locks in favor of these ones.

	Then we should be able to have a tny_folder_set_mutex method. What
would we do with this? Make a TnyMergeFolder have the same lock of its
children and then make access to the merge folder act as it was only a
folder at lock level.

	Would it help a bit with locking problems?
Index: ChangeLog
===================================================================
--- ChangeLog	(revisión: 2507)
+++ ChangeLog	(copia de trabajo)
@@ -1,3 +1,10 @@
+2007-07-26  Jose Dapena Paz  <jdapena igalia com>
+
+	* libtinymail/tny-merge-folder.c:
+	now we use a separate lock for observers list and
+	folder lock itself. This should prevent interlock
+	problems due to notify dependency with inner folders.
+
 2007-07-26  Philip Van Hoof  <pvanhoof gnome org>
 
 	* More granularity in the locking of the POP code
Index: libtinymail/tny-merge-folder.c
===================================================================
--- libtinymail/tny-merge-folder.c	(revisión: 2507)
+++ libtinymail/tny-merge-folder.c	(copia de trabajo)
@@ -35,6 +35,7 @@
 {
 	gchar *id, *name;
 	TnyList *mothers, *observers;
+	GStaticRecMutex *observers_lock;
 	GStaticRecMutex *lock;
 	TnyFolderType folder_type;
 };
@@ -51,13 +52,13 @@
 	TnyList *copy = NULL;
 	TnyIterator *iter;
 
-	g_static_rec_mutex_lock (priv->lock);
+	g_static_rec_mutex_lock (priv->observers_lock);
 	if (!priv->observers) {
-		g_static_rec_mutex_unlock (priv->lock);
+		g_static_rec_mutex_unlock (priv->observers_lock);
 		return;
 	}
 	copy = tny_list_copy (priv->observers);
-	g_static_rec_mutex_unlock (priv->lock);
+	g_static_rec_mutex_unlock (priv->observers_lock);
 
 	iter = tny_list_create_iterator (copy);
 	while (!tny_iterator_is_done (iter))
@@ -1035,14 +1036,14 @@
 {
 	TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self);
 
-	g_static_rec_mutex_lock (priv->lock);
+	g_static_rec_mutex_lock (priv->observers_lock);
 
 	if (!priv->observers)
 		priv->observers = tny_simple_list_new ();
 
 	tny_list_prepend (priv->observers, G_OBJECT (observer));
 
-	g_static_rec_mutex_unlock (priv->lock);
+	g_static_rec_mutex_unlock (priv->observers_lock);
 
 	return;
 }
@@ -1052,12 +1053,12 @@
 {
 	TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self);
 
-	g_static_rec_mutex_lock (priv->lock);
+	g_static_rec_mutex_lock (priv->observers_lock);
 
 	if (priv->observers)
 		tny_list_remove (priv->observers, G_OBJECT (observer));
 
-	g_static_rec_mutex_unlock (priv->lock);
+	g_static_rec_mutex_unlock (priv->observers_lock);
 
 	return;
 }
@@ -1243,7 +1244,9 @@
 	
 	priv->mothers = tny_simple_list_new ();
 	priv->lock = g_new0 (GStaticRecMutex, 1);
+	priv->observers_lock = g_new0 (GStaticRecMutex, 1);
 	g_static_rec_mutex_init (priv->lock);
+	g_static_rec_mutex_init (priv->observers_lock);
 	priv->observers = NULL;
 	priv->folder_type = TNY_FOLDER_TYPE_MERGE;
 
@@ -1257,6 +1260,14 @@
 	TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self);
 	TnyIterator *iter;
 
+	g_static_rec_mutex_lock (priv->observers_lock);
+	if (priv->observers) 
+		g_object_unref (priv->observers);
+
+	priv->observers_lock = NULL;
+	g_static_rec_mutex_unlock (priv->observers_lock);
+	g_static_rec_mutex_free (priv->observers_lock);
+
 	g_static_rec_mutex_lock (priv->lock);
 
 	iter = tny_list_create_iterator (priv->mothers);
@@ -1269,9 +1280,6 @@
 	}
 	g_object_unref (iter);
 
-	if (priv->observers) 
-		g_object_unref (priv->observers);
-
 	g_object_unref (priv->mothers);
 
 	if (priv->id)
@@ -1281,7 +1289,6 @@
 		g_free (priv->name);
 
 	g_static_rec_mutex_unlock (priv->lock);
-
 	g_static_rec_mutex_free (priv->lock);
 	priv->lock = NULL;
 


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