diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2011-04-28 09:43:40 +0800 |
---|---|---|
committer | Rodrigo Moya <rodrigo@gnome-db.org> | 2011-06-30 00:42:03 +0800 |
commit | 900fd0a2ad5c4a2f1915f92ee980073af740c8b2 (patch) | |
tree | 9efbbef24072a40f125d06d503153800e3c184b6 | |
parent | 76b102e4038c63e29e4b427e4bdfe4db720970f2 (diff) | |
download | gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar.gz gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar.bz2 gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar.lz gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar.xz gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.tar.zst gsoc2013-evolution-900fd0a2ad5c4a2f1915f92ee980073af740c8b2.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.
-rw-r--r-- | 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 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 ( |