[gedit] open-document-selector: Properly remove idle



commit e88b8456cfd4aa969b43594b0748837db4988fed
Author: Andrea Azzarone <andrea azzarone canonical com>
Date:   Tue Apr 2 17:33:12 2019 +0100

    open-document-selector: Properly remove idle
    
    It's not possible to use g_idle_remove_by_data when the idle was added with
    gdk_threads_add_idle_full. gdk_threads_add_idle_full uses g_idle_add_full
    internally but it creates a temporary data strucuture. The address of this
    temporary data structure should be passed to g_idle_remove_by_data. For obvious
    reasons we cannot do that, so let's use g_source_remove.
    
    Failing to remove the idle when the open document selector is disposed could
    result in a crash because the idle function (real_populate_liststore) would
    access invalid memory.
    
    Also remove populate_scheduled because it's not needed for two reasons:
    1. populate_liststore and real_populate_liststore always run in the same thread
    2. if populate_liststore is called before real_populate_liststore is run, there
       is no need to schedule two calls two real_populate_liststore.
    
    Close: https://bugs.launchpad.net/bugs/1646762

 gedit/gedit-open-document-selector.c | 36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)
---
diff --git a/gedit/gedit-open-document-selector.c b/gedit/gedit-open-document-selector.c
index 847807a51..f67a6ba6d 100644
--- a/gedit/gedit-open-document-selector.c
+++ b/gedit/gedit-open-document-selector.c
@@ -51,6 +51,8 @@ struct _GeditOpenDocumentSelector
        GtkWidget *placeholder_box;
        GtkWidget *scrolled_window;
 
+       guint populate_listbox_id;
+
        GdkRGBA name_label_color;
        PangoFontDescription *name_font;
        GdkRGBA path_label_color;
@@ -66,9 +68,6 @@ struct _GeditOpenDocumentSelector
        GList *active_doc_dir_items;
        GList *current_docs_items;
        GList *all_items;
-
-       guint populate_liststore_is_idle : 1;
-       guint populate_scheduled : 1;
 };
 
 typedef enum
@@ -540,7 +539,6 @@ real_populate_liststore (gpointer data)
        GList *filter_items = NULL;
        gchar *filter;
        GRegex *filter_regex = NULL;
-       selector->populate_liststore_is_idle = FALSE;
 
        DEBUG_SELECTOR_TIMER_DECL
        DEBUG_SELECTOR_TIMER_NEW
@@ -608,33 +606,25 @@ real_populate_liststore (gpointer data)
                                  selector, DEBUG_SELECTOR_TIMER_GET););
        DEBUG_SELECTOR_TIMER_DESTROY
 
-       if (selector->populate_scheduled)
-       {
-               selector->populate_scheduled = FALSE;
-               return G_SOURCE_CONTINUE;
-       }
-       else
-       {
-               return G_SOURCE_REMOVE;
-       }
+       selector->populate_listbox_id = 0;
+       return G_SOURCE_REMOVE;
 }
 
 static void
 populate_liststore (GeditOpenDocumentSelector *selector)
 {
        /* Populate requests are compressed */
-       if (selector->populate_liststore_is_idle)
+       if (selector->populate_listbox_id != 0)
        {
                DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: idle\n", selector););
-
-               selector->populate_scheduled = TRUE;
                return;
        }
 
        DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: scheduled\n", selector););
-
-       selector->populate_liststore_is_idle = TRUE;
-       gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30, real_populate_liststore, selector, NULL);
+       selector->populate_listbox_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
+                                                                  real_populate_liststore,
+                                                                  selector,
+                                                                  NULL);
 }
 
 static gboolean
@@ -740,12 +730,10 @@ gedit_open_document_selector_dispose (GObject *object)
 {
        GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
 
-       while (TRUE)
+       if (selector->populate_listbox_id != 0)
        {
-               if (!g_idle_remove_by_data (selector))
-               {
-                       break;
-               }
+               g_source_remove (selector->populate_listbox_id);
+               selector->populate_listbox_id = 0;
        }
 
        g_clear_pointer (&selector->name_font, pango_font_description_free);


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