aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-04-28 09:43:40 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-04-28 09:48:06 +0800
commit1f192fbb46ce36012ce3131eda9a818521985493 (patch)
treed732fa104a8c887b2abb4e0b2a64059ba01d0f20 /mail
parent521caf8b6cbe648e8f5c5d6104cc58bb8446e0e3 (diff)
downloadgsoc2013-evolution-1f192fbb46ce36012ce3131eda9a818521985493.tar.gz
gsoc2013-evolution-1f192fbb46ce36012ce3131eda9a818521985493.tar.zst
gsoc2013-evolution-1f192fbb46ce36012ce3131eda9a818521985493.zip
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.
Diffstat (limited to 'mail')
-rw-r--r--mail/e-mail-migrate.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index d627088254..1c20791edc 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 */
@@ -514,20 +516,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,
@@ -539,16 +550,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 (