[evolution/gnome-3-0] Bug 597082 - Crash while migrating folder info



commit 967c83c8a95017fc804d066dbbd52921d11c1e13
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Apr 27 21:43:40 2011 -0400

    Bug 597082 - Crash while migrating folder info
    
    In migrate_folders(), free the idle callback closure using a
    GDestroyNotify callback so we don't try to free the same memory
    repeatedly if the idle callback recurses while cycling the main loop.
    
    Why *are* we cycling the main loop anyway?  I don't get that part.
    
    (cherry picked from commit 1f192fbb46ce36012ce3131eda9a818521985493)

 mail/e-mail-migrate.c |   36 +++++++++++++++++++++++++-----------
 1 files changed, 25 insertions(+), 11 deletions(-)
---
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index 2f3ce8b..6128322 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -65,13 +65,15 @@
 
 #define d(x) x
 
-struct _migrate_state_info {
+typedef struct _MigrateStateInfo MigrateStateInfo;
+
+struct _MigrateStateInfo {
 	gchar *label_name;
 	gdouble progress;
 };
 
 static gboolean
-update_states_in_main_thread (const struct _migrate_state_info *info);
+update_states_in_main_thread (MigrateStateInfo *info);
 
 /* 1.4 upgrade functions */
 
@@ -519,20 +521,29 @@ em_update_sa_junk_setting_2_23 (void)
 #ifndef G_OS_WIN32
 
 static gboolean
-update_states_in_main_thread (const struct _migrate_state_info * info)
+update_states_in_main_thread (MigrateStateInfo *info)
 {
 	g_return_val_if_fail (info != NULL, FALSE);
 	g_return_val_if_fail (info->label_name != NULL, FALSE);
+
 	em_migrate_set_progress (info->progress);
 	em_migrate_set_folder_name (info->label_name);
-	g_free (info->label_name);
-	g_free ( (gpointer)info);
+
+	/* XXX Why is this necessary? */
 	while (gtk_events_pending ())
 		gtk_main_iteration ();
+
 	return FALSE;
 }
 
 static void
+migrate_state_info_free (MigrateStateInfo *info)
+{
+	g_free (info->label_name);
+	g_slice_free (MigrateStateInfo, info);
+}
+
+static void
 migrate_folders (CamelStore *store,
                  gboolean is_local,
                  CamelFolderInfo *fi,
@@ -544,16 +555,19 @@ migrate_folders (CamelStore *store,
 	CamelFolder *folder;
 
 	while (fi) {
-
-		struct _migrate_state_info *info = g_malloc (sizeof (struct
-					_migrate_state_info));
-		info->label_name = g_strdup_printf ("%s/%s", acc,
-				fi->full_name);
+		MigrateStateInfo *info;
 
 		*nth_folder = *nth_folder + 1;
 
+		info = g_slice_new0 (MigrateStateInfo);
+		info->label_name = g_strdup_printf (
+			"%s/%s", acc, fi->full_name);
 		info->progress = (double) (*nth_folder) / total_folders;
-		g_idle_add ((GSourceFunc) update_states_in_main_thread, info);
+
+		g_idle_add_full (
+			G_PRIORITY_LOW, (GSourceFunc)
+			update_states_in_main_thread, info,
+			(GDestroyNotify) migrate_state_info_free);
 
 		if (is_local)
 			folder = camel_store_get_folder_sync (



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