From e151ddc95de6d26c93b6850a5e89e1c8288f3dcb Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 22 Nov 2010 21:16:15 +0100 Subject: [PATCH] Bug #635550 - e-calendar-factory leaks memory --- calendar/libedata-cal/e-cal-backend-file-store.c | 2 - calendar/libedata-cal/e-cal-backend-intervaltree.c | 31 +++++++++---- calendar/libedata-cal/test-intervaltree.c | 54 ++++++++++++++++++---- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/calendar/libedata-cal/e-cal-backend-file-store.c b/calendar/libedata-cal/e-cal-backend-file-store.c index fd07797..cd6ab59 100644 --- a/calendar/libedata-cal/e-cal-backend-file-store.c +++ b/calendar/libedata-cal/e-cal-backend-file-store.c @@ -831,8 +831,6 @@ timeout_save_cache (gpointer user_data) if (g_rename (tmpfile, priv->cache_file_name) != 0) g_unlink (tmpfile); - e_file_cache_thaw_changes (priv->keys_cache); - error: g_static_rw_lock_reader_unlock (&priv->lock); g_free (tmpfile); diff --git a/calendar/libedata-cal/e-cal-backend-intervaltree.c b/calendar/libedata-cal/e-cal-backend-intervaltree.c index 7e069d4..c1112ba 100644 --- a/calendar/libedata-cal/e-cal-backend-intervaltree.c +++ b/calendar/libedata-cal/e-cal-backend-intervaltree.c @@ -291,6 +291,10 @@ e_intervaltree_insert (EIntervalTree *tree, time_t start, time_t end, ECalCompon g_static_rec_mutex_lock (&priv->mutex); + e_cal_component_get_uid (comp, &uid); + rid = e_cal_component_get_recurid_as_string (comp); + e_intervaltree_remove (tree, uid, rid); + x = g_new (EIntervalNode, 1); x->min = x->start = start; x->max = x->end = end; @@ -354,8 +358,6 @@ e_intervaltree_insert (EIntervalTree *tree, time_t start, time_t end, ECalCompon } priv->root->left->red = FALSE; - e_cal_component_get_uid (comp, &uid); - rid = e_cal_component_get_recurid_as_string (comp); g_hash_table_insert (priv->id_node_hash, component_key (uid, rid), newNode); g_free (rid); @@ -615,12 +617,15 @@ e_intervaltree_dump (EIntervalTree *tree) /** * Caller should hold the lock. **/ -static EIntervalNode* +static EIntervalNode * e_intervaltree_search_component (EIntervalTree *tree, const gchar *searched_uid, const gchar *searched_rid) { EIntervalTreePrivate *priv; + EIntervalNode *node; + gchar *key; + g_return_val_if_fail (tree != NULL, NULL); g_return_val_if_fail (searched_uid != NULL, NULL); @@ -633,7 +638,11 @@ e_intervaltree_search_component (EIntervalTree *tree, return NULL; } - return g_hash_table_lookup (priv->id_node_hash, component_key (searched_uid, searched_rid)); + key = component_key (searched_uid, searched_rid); + node = g_hash_table_lookup (priv->id_node_hash, key); + g_free (key); + + return node; } /** @@ -652,6 +661,7 @@ e_intervaltree_remove (EIntervalTree *tree, EIntervalNode *x; EIntervalNode *z; EIntervalNode *nil, *root; + gchar *key; g_return_val_if_fail (tree != NULL, FALSE); @@ -662,9 +672,7 @@ e_intervaltree_remove (EIntervalTree *tree, z = e_intervaltree_search_component (tree, uid, rid); - if (!z || z == nil) - { - g_message (G_STRLOC ": Cannot remove node - could not find node in tree\n"); + if (!z || z == nil) { g_static_rec_mutex_unlock (&priv->mutex); return FALSE; } @@ -722,7 +730,9 @@ e_intervaltree_remove (EIntervalTree *tree, e_intervaltree_fixup_deletion (tree, x); } - g_hash_table_remove (priv->id_node_hash, component_key (uid, rid)); + key = component_key (uid, rid); + g_hash_table_remove (priv->id_node_hash, key); + g_free (key); g_object_unref (z->comp); g_free (z); @@ -769,8 +779,9 @@ e_intervaltree_init (EIntervalTree *tree) { EIntervalTreePrivate *priv; EIntervalNode *root, *nil; - priv = g_new0 (EIntervalTreePrivate, 1); - tree->priv = priv; + + tree->priv = E_INTERVALTREE_GET_PRIVATE (tree); + priv = tree->priv; priv->nil = nil = g_new (EIntervalNode, 1); nil->parent = nil->left = nil->right = nil; diff --git a/calendar/libedata-cal/test-intervaltree.c b/calendar/libedata-cal/test-intervaltree.c index 65a5f37..34e9853 100644 --- a/calendar/libedata-cal/test-intervaltree.c +++ b/calendar/libedata-cal/test-intervaltree.c @@ -144,7 +144,7 @@ static ECalComponent* create_test_component (time_t start, time_t end) { ECalComponent *comp = e_cal_component_new (); - ECalComponentText *summary; + ECalComponentText summary; struct icaltimetype current; e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT); @@ -162,12 +162,12 @@ create_test_component (time_t start, time_t end) e_cal_component_set_dtend (comp, &dtend); */ - summary = g_new (ECalComponentText, 1); + summary.value = g_strdup_printf ("%ld - %ld", start, end); + summary.altrep = NULL; - summary->value = g_strdup_printf ("%ld - %ld", start, end); - summary->altrep = NULL; + e_cal_component_set_summary (comp, &summary); - e_cal_component_set_summary (comp, summary); + g_free ((gchar *) summary.value); current = icaltime_from_timet (time (NULL), 0); e_cal_component_set_created (comp, ¤t); @@ -213,7 +213,7 @@ print_list (GList *l2) */ static void -random_test () +random_test (void) { /* * outline: @@ -248,7 +248,6 @@ random_test () interval->start = start; interval->end = end; interval->comp = comp; - g_object_ref (comp); list = g_list_insert (list, interval, -1); @@ -271,7 +270,6 @@ random_test () interval->start = start; interval->end = _TIME_MAX; interval->comp = comp; - g_object_ref (comp); list = g_list_insert (list, interval, -1); e_intervaltree_insert (tree, start, interval->end, comp); @@ -416,12 +414,52 @@ random_test () g_list_free (list); } +static void +mem_test (void) +{ + EIntervalTree *tree; + time_t start = 10, end = 50; + ECalComponent *comp = create_test_component (start, end), *clone_comp; + const gchar *uid; + gchar *rid; + + tree = e_intervaltree_new (); + + g_assert (((GObject *) comp)->ref_count == 1); + e_intervaltree_insert (tree, start, end, comp); + g_assert (((GObject *) comp)->ref_count == 2); + + e_cal_component_get_uid (comp, &uid); + rid = e_cal_component_get_recurid_as_string (comp); + e_intervaltree_remove (tree, uid, rid); + g_free (rid); + g_assert (((GObject *) comp)->ref_count == 1); + + e_intervaltree_insert (tree, start, end, comp); + g_assert (((GObject *) comp)->ref_count == 2); + + clone_comp = e_cal_component_clone (comp); + e_intervaltree_insert (tree, start, end, clone_comp); + + g_assert (((GObject *) comp)->ref_count == 1); + g_assert (((GObject *) clone_comp)->ref_count == 2); + + e_intervaltree_destroy (tree); + + g_assert (((GObject *) comp)->ref_count == 1); + g_assert (((GObject *) clone_comp)->ref_count == 1); + + g_object_unref (comp); + g_object_unref (clone_comp); +} + gint main (gint argc, gchar **argv) { g_type_init (); myrand = g_rand_new (); + mem_test (); random_test (); g_print ("Everything OK\n"); -- 2.7.4