[evolution-data-server/gnome-3-4] Bug #680211 - Memory usage increases on each folder select
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-4] Bug #680211 - Memory usage increases on each folder select
- Date: Fri, 20 Jul 2012 16:05:29 +0000 (UTC)
commit 6cfd76b0b2545306662b669b0535253a30a24304
Author: Milan Crha <mcrha redhat com>
Date: Fri Jul 20 18:05:05 2012 +0200
Bug #680211 - Memory usage increases on each folder select
camel/camel-folder-summary.c | 51 ++++++++++++++++++++++++++++-
camel/providers/imap/camel-imap-folder.c | 29 ++++++----------
camel/providers/imap/camel-imap-store.c | 2 +
3 files changed, 62 insertions(+), 20 deletions(-)
---
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 024b3d4..75213b9 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -167,6 +167,37 @@ enum {
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, CAMEL_TYPE_OBJECT)
+static gboolean
+remove_each_item (gpointer uid,
+ gpointer mi,
+ gpointer user_data)
+{
+ GSList **to_remove_infos = user_data;
+
+ *to_remove_infos = g_slist_prepend (*to_remove_infos, mi);
+
+ return TRUE;
+}
+
+static void
+remove_all_loaded (CamelFolderSummary *summary)
+{
+ GSList *to_remove_infos = NULL;
+
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
+ g_hash_table_foreach_remove (summary->priv->loaded_infos, remove_each_item, &to_remove_infos);
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
+
+ g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_free, NULL);
+ g_slist_free (to_remove_infos);
+
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+}
+
static void
free_o_name (gpointer key,
gpointer value,
@@ -184,6 +215,8 @@ folder_summary_dispose (GObject *object)
priv = CAMEL_FOLDER_SUMMARY_GET_PRIVATE (object);
if (priv->timeout_handle) {
+ /* this should not happen, because the release timer
+ holds a reference on object */
g_source_remove (priv->timeout_handle);
priv->timeout_handle = 0;
}
@@ -228,6 +261,11 @@ folder_summary_dispose (GObject *object)
priv->index = NULL;
}
+ if (priv->folder) {
+ g_object_weak_unref (G_OBJECT (priv->folder), (GWeakNotify) g_nullify_pointer, &priv->folder);
+ priv->folder = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_folder_summary_parent_class)->dispose (object);
}
@@ -239,6 +277,7 @@ folder_summary_finalize (GObject *object)
CamelFolderSummaryPrivate *priv = summary->priv;
g_hash_table_destroy (priv->uids);
+ remove_all_loaded (summary);
g_hash_table_destroy (priv->loaded_infos);
g_hash_table_foreach (priv->filter_charset, free_o_name, NULL);
@@ -265,6 +304,8 @@ folder_summary_set_folder (CamelFolderSummary *summary,
/* folder can be NULL in certain cases, see maildir-store */
summary->priv->folder = folder;
+ if (folder)
+ g_object_weak_ref (G_OBJECT (folder), (GWeakNotify) g_nullify_pointer, &summary->priv->folder);
}
static void
@@ -1961,6 +2002,8 @@ cfs_try_release_memory (CamelFolderSummary *summary)
if (!summary->priv->folder || !g_hash_table_size (summary->priv->loaded_infos)) {
summary->priv->cache_load_time = 0;
summary->priv->timeout_handle = 0;
+ g_object_unref (summary);
+
return FALSE;
}
@@ -1993,8 +2036,10 @@ cfs_schedule_info_release_timer (CamelFolderSummary *summary)
}
/* FIXME[disk-summary] LRU please and not timeouts */
- if (can_do)
- summary->priv->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, summary);
+ if (can_do) {
+ summary->priv->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP,
+ (GSourceFunc) cfs_try_release_memory, g_object_ref (summary));
+ }
}
/* update also cache load time to the actual, to not release something just loaded */
@@ -3151,6 +3196,7 @@ camel_folder_summary_clear (CamelFolderSummary *summary,
}
g_hash_table_remove_all (summary->priv->uids);
+ remove_all_loaded (summary);
g_hash_table_remove_all (summary->priv->loaded_infos);
summary->priv->saved_count = 0;
@@ -4426,6 +4472,7 @@ camel_message_info_free (gpointer o)
if (mi->summary->priv->build_content
&& ((CamelMessageInfoBase *) mi)->content) {
camel_folder_summary_content_info_free (mi->summary, ((CamelMessageInfoBase *) mi)->content);
+ ((CamelMessageInfoBase *) mi)->content = NULL;
}
CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->message_info_free (mi->summary, mi);
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index e771152..1a172c9 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -1442,6 +1442,7 @@ get_matching (CamelFolder *folder,
if (count1 != count2) {
g_list_free (list2);
+ camel_message_info_free ((CamelMessageInfo *) info);
close_range ();
continue;
}
@@ -1453,6 +1454,7 @@ get_matching (CamelFolder *folder,
if (cmp) {
g_list_free (list2);
+ camel_message_info_free ((CamelMessageInfo *) info);
close_range ();
continue;
}
@@ -1657,19 +1659,13 @@ imap_synchronize_sync (CamelFolder *folder,
/* deleted_uids is NULL when not using real trash */
folder_path = camel_imap_settings_dup_real_trash_path (
CAMEL_IMAP_SETTINGS (settings));
- if (folder_path != NULL) {
+ if (folder_path != NULL && *folder_path) {
if ((folder->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0) {
/* syncing the trash, expunge deleted when found any */
real_trash = g_object_ref (folder);
} else {
real_trash = camel_store_get_trash_folder_sync (
parent_store, cancellable, NULL);
-
- if (folder_path == NULL && real_trash) {
- /* failed to open real trash */
- g_object_unref (real_trash);
- real_trash = NULL;
- }
}
}
g_free (folder_path);
@@ -1680,7 +1676,7 @@ imap_synchronize_sync (CamelFolder *folder,
/* junked_uids is NULL when not using real junk */
folder_path = camel_imap_settings_dup_real_junk_path (
CAMEL_IMAP_SETTINGS (settings));
- if (folder_path != NULL) {
+ if (folder_path != NULL && *folder_path) {
if ((folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0) {
/* syncing the junk, but cannot move
* messages to itself, thus do nothing */
@@ -1688,12 +1684,6 @@ imap_synchronize_sync (CamelFolder *folder,
} else {
real_junk = camel_store_get_junk_folder_sync (
parent_store, cancellable, NULL);
-
- if (folder_path == NULL && real_junk) {
- /* failed to open real junk */
- g_object_unref (real_junk);
- real_junk = NULL;
- }
}
}
g_free (folder_path);
@@ -1736,6 +1726,8 @@ imap_synchronize_sync (CamelFolder *folder,
if (!camel_imap_store_connected (store, NULL)) {
g_free (set);
camel_message_info_free (info);
+ g_ptr_array_foreach (matches, (GFunc) camel_message_info_free, NULL);
+ g_ptr_array_free (matches, TRUE);
break;
}
@@ -1805,10 +1797,7 @@ imap_synchronize_sync (CamelFolder *folder,
camel_folder_summary_touch (folder->summary);
}
- for (j = 0; j < matches->len; j++) {
- info = matches->pdata[j];
- camel_message_info_free (&info->info);
- }
+ g_ptr_array_foreach (matches, (GFunc) camel_message_info_free, NULL);
g_ptr_array_free (matches, TRUE);
/* We unlock here so that other threads can have a chance to grab the connect_lock */
@@ -1829,6 +1818,10 @@ imap_synchronize_sync (CamelFolder *folder,
g_object_unref (real_trash);
if (real_junk)
g_object_unref (real_junk);
+
+ g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
+ g_ptr_array_free (summary, TRUE);
+
return FALSE;
}
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 25c789a..f9badb1 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -2209,6 +2209,8 @@ imap_store_get_folder_sync (CamelStore *store,
new_folder = camel_imap_folder_new (store, folder_name, folder_dir, error);
g_free (folder_dir);
if (new_folder) {
+ if (imap_store->current_folder)
+ g_object_unref (imap_store->current_folder);
imap_store->current_folder = g_object_ref (new_folder);
if (!camel_imap_folder_selected (
new_folder, response, cancellable, error)) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]