Patch: load summary on processing folder-tracking-changed



	Hi,

	This patch for folder_tracking_changed handler in TnyCamelFolder should
avoid crashes caused by freeing the camel folder before the folder
changed event is processed completely.

	With the new implementation we refactor to use exactly the same handler
for folder_changed and folder_tracking_changed. What we do now is
loading the summary in the case we get an external (camel originated)
change in the summary, and use the standard tinymail camel folder reason
system.

Changelog entry:
	* libtinymail-camel/tny-camel-folder.c (folder_tracking_changed):
	reimplemented to load the summary when we get a folder changed
	event from camel, and use the standard folder_changed handler.
	Avoids crashes if the camel folder is freed earlier than
	folder changed handling finishes.


-- 
José Dapena Paz <jdapena igalia com>
Igalia
diff --git a/ChangeLog b/ChangeLog
index 9f9cddf..93e0a9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-07-21  Jose Dapena Paz  <jdapena igalia com>
+
+	* libtinymail-camel/tny-camel-folder.c (folder_tracking_changed):
+	reimplemented to load the summary when we get a folder changed
+	event from camel, and use the standard folder_changed handler.
+	Avoids crashes if the camel folder is freed earlier than
+	folder changed handling finishes.
+
 2009-07-16  Sergio Villar Senin  <svillar igalia com>
 
 	* libtinymail-camel/tny-camel-folder.c (folder_tracking_changed):
diff --git a/libtinymail-camel/tny-camel-folder.c b/libtinymail-camel/tny-camel-folder.c
index 2fe9015..c61dc70 100644
--- a/libtinymail-camel/tny-camel-folder.c
+++ b/libtinymail-camel/tny-camel-folder.c
@@ -89,6 +89,8 @@ static GObjectClass *parent_class = NULL;
 
 
 static void tny_camel_folder_transfer_msgs_shared (TnyFolder *self, TnyList *headers, TnyFolder *folder_dst, gboolean delete_originals, TnyList *new_headers, GError **err);
+static gboolean load_folder_no_lock (TnyCamelFolderPriv *priv);
+static void folder_changed (CamelFolder *camel_folder, CamelFolderChangeInfo *info, gpointer user_data);
 
 
 
@@ -338,33 +340,20 @@ folder_tracking_changed (CamelFolder *camel_folder, CamelFolderChangeInfo *info,
 	   this notification will be received by folder_changed as
 	   well. Checks for folder_changed_id and loaded are harmless
 	   and unlikely needed */
-	if (priv->folder && priv->folder_changed_id && priv->loaded)
-		return;
-
-	if (!priv->handle_changes)
+	g_static_rec_mutex_lock (priv->folder_lock);
+	if (priv->folder && priv->folder_changed_id && priv->loaded) {
+		g_static_rec_mutex_unlock (priv->folder_lock);
 		return;
+	}
 
-	if (!g_static_rec_mutex_trylock (priv->folder_lock)) {
+	_tny_camel_folder_reason (priv);
+	if (!load_folder_no_lock (priv)) {
 		g_static_rec_mutex_unlock (priv->folder_lock);
 		return;
 	}
 
-	/* Update message counts */
-	priv->cached_length = (guint) camel_folder_get_message_count (camel_folder);
-	priv->unread_length = (guint) camel_folder_get_unread_message_count (camel_folder);
-	change = tny_folder_change_new (TNY_FOLDER (self));
-
-	/* Update iter */
-	update_iter_counts (priv);
-	g_static_rec_mutex_unlock (priv->folder_lock);
-
-	tny_folder_change_set_new_unread_count (change, priv->unread_length);
-	tny_folder_change_set_new_all_count (change, priv->cached_length);
-	priv->dont_fkill = TRUE;
-	notify_folder_observers_about_in_idle (TNY_FOLDER (self), change,
-					       TNY_FOLDER_PRIV_GET_SESSION (priv));
-	g_object_unref (change);
-	priv->dont_fkill = old;
+	folder_changed (camel_folder, info, priv);
+	_tny_camel_folder_unreason (priv);
 
 	return;
 }


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