diff options
author | Havoc Pennington <hp@redhat.com> | 2001-09-21 23:56:43 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-09-21 23:56:43 +0000 |
commit | b7eec02f2ae69ed2a3de51981aabc8a9e2432ef5 (patch) | |
tree | f29626e12026fa766169b6935a24fa780c4f76f9 /gtk | |
parent | 615b641adaab7f6cd86d077cd9590dd753a075e4 (diff) | |
download | gtk+-b7eec02f2ae69ed2a3de51981aabc8a9e2432ef5.tar.gz |
Bug #60862
2001-09-21 Havoc Pennington <hp@redhat.com>
Bug #60862
* gtk/gtktextbtree.c (gtk_text_btree_node_destroy):
(_gtk_text_btree_unref): fix up mark memory management
* gtk/gtktextmark.c (mark_segment_delete_func): ditto
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtktextbtree.c | 61 | ||||
-rw-r--r-- | gtk/gtktextbtree.h | 3 | ||||
-rw-r--r-- | gtk/gtktextmark.c | 18 | ||||
-rw-r--r-- | gtk/gtktexttagtable.c | 2 |
4 files changed, 41 insertions, 43 deletions
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c index 7d6f51adad..810f3405f8 100644 --- a/gtk/gtktextbtree.c +++ b/gtk/gtktextbtree.c @@ -481,16 +481,6 @@ _gtk_text_btree_ref (GtkTextBTree *tree) tree->refcount += 1; } -static void -mark_destroy_foreach (gpointer key, gpointer value, gpointer user_data) -{ - GtkTextLineSegment *seg = value; - - g_return_if_fail (seg->body.mark.tree == NULL); - - g_object_unref (G_OBJECT (seg->body.mark.obj)); -} - void _gtk_text_btree_unref (GtkTextBTree *tree) { @@ -503,9 +493,7 @@ _gtk_text_btree_unref (GtkTextBTree *tree) { gtk_text_btree_node_destroy (tree, tree->root_node); - g_hash_table_foreach (tree->mark_table, - mark_destroy_foreach, - NULL); + g_assert (g_hash_table_size (tree->mark_table) == 0); g_hash_table_destroy (tree->mark_table); g_object_unref (G_OBJECT (tree->insert_mark)); @@ -757,7 +745,7 @@ _gtk_text_btree_delete (GtkTextIter *start, next = seg->next; char_count = seg->char_count; - if ((*seg->type->deleteFunc)(seg, curline, 0) != 0) + if ((*seg->type->deleteFunc)(seg, curline, FALSE) != 0) { /* * This segment refuses to die. Move it to prev_seg and @@ -2689,8 +2677,25 @@ _gtk_text_btree_remove_mark_by_name (GtkTextBTree *tree, } void +_gtk_text_btree_release_mark_segment (GtkTextBTree *tree, + GtkTextLineSegment *segment) +{ + + if (segment->body.mark.name) + g_hash_table_remove (tree->mark_table, segment->body.mark.name); + + segment->body.mark.tree = NULL; + segment->body.mark.line = NULL; + + /* Remove the ref on the mark, which frees segment as a side effect + * if this is the last reference. + */ + g_object_unref (G_OBJECT (segment->body.mark.obj)); +} + +void _gtk_text_btree_remove_mark (GtkTextBTree *tree, - GtkTextMark *mark) + GtkTextMark *mark) { GtkTextLineSegment *segment; @@ -2707,34 +2712,27 @@ _gtk_text_btree_remove_mark (GtkTextBTree *tree, /* This calls cleanup_line and segments_changed */ gtk_text_btree_unlink_segment (tree, segment, segment->body.mark.line); - - if (segment->body.mark.name) - g_hash_table_remove (tree->mark_table, segment->body.mark.name); - - /* Remove the ref on the mark that belonged to the segment. */ - g_object_unref (G_OBJECT (mark)); - - segment->body.mark.tree = NULL; - segment->body.mark.line = NULL; + + _gtk_text_btree_release_mark_segment (tree, segment); } gboolean _gtk_text_btree_mark_is_insert (GtkTextBTree *tree, - GtkTextMark *segment) + GtkTextMark *segment) { return segment == tree->insert_mark; } gboolean _gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree, - GtkTextMark *segment) + GtkTextMark *segment) { return segment == tree->selection_bound_mark; } GtkTextMark* _gtk_text_btree_get_mark_by_name (GtkTextBTree *tree, - const gchar *name) + const gchar *name) { GtkTextLineSegment *seg; @@ -5123,14 +5121,7 @@ gtk_text_btree_node_destroy (GtkTextBTree *tree, GtkTextBTreeNode *node) seg = line->segments; line->segments = seg->next; - if (GTK_IS_TEXT_MARK_SEGMENT (seg)) - { - /* Set the mark as deleted */ - seg->body.mark.tree = NULL; - seg->body.mark.line = NULL; - } - - (*seg->type->deleteFunc) (seg, line, 1); + (*seg->type->deleteFunc) (seg, line, TRUE); } gtk_text_line_destroy (tree, line); } diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h index 723746d94f..4e3b122368 100644 --- a/gtk/gtktextbtree.h +++ b/gtk/gtktextbtree.h @@ -276,6 +276,9 @@ void _gtk_change_node_toggle_count (GtkTextBTreeNode *node, GtkTextTagInfo *info, gint delta); +/* for gtktextmark.c */ +void _gtk_text_btree_release_mark_segment (GtkTextBTree *tree, + GtkTextLineSegment *segment); #ifdef __cplusplus } diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c index 018eb089b5..1be324b11a 100644 --- a/gtk/gtktextmark.c +++ b/gtk/gtktextmark.c @@ -113,8 +113,6 @@ gtk_text_mark_finalize (GObject *obj) if (seg) { - g_return_if_fail (seg->body.mark.tree == NULL); - if (seg->body.mark.tree != NULL) g_warning ("GtkTextMark being finalized while still in the buffer; " "someone removed a reference they didn't own! Crash " @@ -320,21 +318,27 @@ GtkTextLineSegmentClass gtk_text_left_mark_type = { * a mark lies in a range of characters being deleted. * * Results: - * Returns 1 to indicate that deletion has been rejected. + * Returns 1 to indicate that deletion has been rejected, + * or 0 otherwise * * Side effects: - * None (even if the whole tree is being deleted we don't - * free up the mark; it will be done elsewhere). + * Frees mark if tree is going away * *-------------------------------------------------------------- */ static gboolean -mark_segment_delete_func (GtkTextLineSegment *segPtr, +mark_segment_delete_func (GtkTextLineSegment *seg, GtkTextLine *line, gboolean tree_gone) { - return TRUE; + if (tree_gone) + { + _gtk_text_btree_release_mark_segment (seg->body.mark.tree, seg); + return FALSE; + } + else + return TRUE; } /* diff --git a/gtk/gtktexttagtable.c b/gtk/gtktexttagtable.c index b20ce3a631..cb246b2636 100644 --- a/gtk/gtktexttagtable.c +++ b/gtk/gtktexttagtable.c @@ -149,7 +149,7 @@ gtk_text_tag_table_finalize (GObject *object) table = GTK_TEXT_TAG_TABLE (object); gtk_text_tag_table_foreach (table, foreach_unref, NULL); - + g_hash_table_destroy (table->hash); g_slist_free (table->anonymous); |