[gtksourceview/wip/fix-ref-cycle: 1/2] SearchContext: weak ref to the buffer



commit b80e7c27db80329530c0dd9836bc5516810ee5c5
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Oct 5 17:40:13 2013 +0200

    SearchContext: weak ref to the buffer
    
    The strong ref prevented the buffer from being finalized.
    Now the search context has a weak ref to the buffer, and vice versa.
    
    Due to the weak ref, we now have to keep a reference to the tag table,
    to be able to remove the found_tag in dispose(). A tag table can be used
    for several buffers.
    
    To create a search context, we have to call
    gtk_source_search_context_new(), and pass the buffer as an argument.
    Another possibility would have been:
    - gtk_source_buffer_create_search_context()
    - gtk_source_buffer_remove_search_context()
    In this case, the buffer can have a strong ref to the search context,
    since the search context is explicitely removed from the buffer. But
    it's too late for doing that, we have to live with the current API.

 gtksourceview/gtksourcesearchcontext.c |   37 ++++++++++++++++++++++++++-----
 1 files changed, 31 insertions(+), 6 deletions(-)
---
diff --git a/gtksourceview/gtksourcesearchcontext.c b/gtksourceview/gtksourcesearchcontext.c
index 88b4072..2a13515 100644
--- a/gtksourceview/gtksourcesearchcontext.c
+++ b/gtksourceview/gtksourcesearchcontext.c
@@ -278,7 +278,12 @@ enum
 
 struct _GtkSourceSearchContextPrivate
 {
+       /* Weak ref to the buffer. The buffer has also a weak ref to the search
+        * context. A strong ref in either direction would prevent the pointed
+        * object to be finalized.
+        */
        GtkTextBuffer *buffer;
+
        GtkSourceSearchSettings *settings;
 
        /* The tag to apply to search occurrences. Even if the highlighting is
@@ -286,6 +291,12 @@ struct _GtkSourceSearchContextPrivate
         */
        GtkTextTag *found_tag;
 
+       /* A reference to the tag table where the found_tag is added. The sole
+        * purpose is to remove the found_tag in dispose(). We can not rely on
+        * 'buffer' since it is a weak reference.
+        */
+       GtkTextTagTable *tag_table;
+
        /* The region to scan and highlight. If NULL, the scan is finished. */
        GtkTextRegion *scan_region;
 
@@ -2473,9 +2484,15 @@ set_buffer (GtkSourceSearchContext *search,
            GtkSourceBuffer        *buffer)
 {
        g_assert (search->priv->buffer == NULL);
+       g_assert (search->priv->tag_table == NULL);
 
        search->priv->buffer = GTK_TEXT_BUFFER (buffer);
-       g_object_ref (search->priv->buffer);
+
+       g_object_add_weak_pointer (G_OBJECT (buffer),
+                                  (gpointer *)&search->priv->buffer);
+
+       search->priv->tag_table = gtk_text_buffer_get_tag_table (search->priv->buffer);
+       g_object_ref (search->priv->tag_table);
 
        g_signal_connect_object (buffer,
                                 "insert-text",
@@ -2587,16 +2604,24 @@ gtk_source_search_context_dispose (GObject *object)
 
        clear_search (search);
 
-       if (search->priv->found_tag != NULL)
+       if (search->priv->found_tag != NULL &&
+           search->priv->tag_table != NULL)
        {
-               GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (search->priv->buffer);
-
-               gtk_text_tag_table_remove (tag_table, search->priv->found_tag);
+               gtk_text_tag_table_remove (search->priv->tag_table,
+                                          search->priv->found_tag);
 
                g_clear_object (&search->priv->found_tag);
+               g_clear_object (&search->priv->tag_table);
+       }
+
+       if (search->priv->buffer != NULL)
+       {
+               g_object_remove_weak_pointer (G_OBJECT (search->priv->buffer),
+                                             (gpointer *)&search->priv->buffer);
+
+               search->priv->buffer = NULL;
        }
 
-       g_clear_object (&search->priv->buffer);
        g_clear_object (&search->priv->settings);
 
        G_OBJECT_CLASS (gtk_source_search_context_parent_class)->dispose (object);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]