Bug #635550 - e-calendar-factory leaks memory
authorMilan Crha <mcrha@redhat.com>
Mon, 22 Nov 2010 20:16:15 +0000 (21:16 +0100)
committerMilan Crha <mcrha@redhat.com>
Mon, 22 Nov 2010 20:16:15 +0000 (21:16 +0100)
calendar/libedata-cal/e-cal-backend-file-store.c
calendar/libedata-cal/e-cal-backend-intervaltree.c
calendar/libedata-cal/test-intervaltree.c

index fd07797..cd6ab59 100644 (file)
@@ -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);
index 7e069d4..c1112ba 100644 (file)
@@ -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;
index 65a5f37..34e9853 100644 (file)
@@ -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, &current);
@@ -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");