[gedit] OpenDocumentSelector: Fetch recent list in an idle



commit 3f9f63285265c4eb2cf221bfd1b74834a3f1c1fa
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Sat Aug 29 19:57:25 2015 +0200

    OpenDocumentSelector: Fetch recent list in an idle
    
    We get some crashes due to the fetching of the recent list
    in a thread like other lists of the store.
    
    GtkRecentManager can't be use in a thread other
    than the main one.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744611

 gedit/gedit-open-document-selector-store.c |  110 +++++++++++++++++----------
 1 files changed, 69 insertions(+), 41 deletions(-)
---
diff --git a/gedit/gedit-open-document-selector-store.c b/gedit/gedit-open-document-selector-store.c
index d990d50..cbd0009 100644
--- a/gedit/gedit-open-document-selector-store.c
+++ b/gedit/gedit-open-document-selector-store.c
@@ -67,6 +67,8 @@ struct _GeditOpenDocumentSelectorStore
 {
        GObject parent_instance;
 
+       GSource *recent_source;
+
        GeditRecentConfiguration recent_config;
        GList *recent_items;
        gint recent_config_limit;
@@ -74,7 +76,6 @@ struct _GeditOpenDocumentSelectorStore
 };
 
 G_LOCK_DEFINE_STATIC (recent_files_filter_lock);
-G_LOCK_DEFINE_STATIC (store_recent_items_lock);
 
 G_DEFINE_TYPE (GeditOpenDocumentSelectorStore, gedit_open_document_selector_store, G_TYPE_OBJECT)
 
@@ -541,15 +542,12 @@ update_list_cb (GeditOpenDocumentSelectorStore *selector_store,
        switch (type)
        {
                case GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST:
-                       G_LOCK (store_recent_items_lock);
-
                        gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
                        selector_store->recent_items = list;
 
-                       DEBUG_SELECTOR (g_print ("\tStore(%p): update_list_cb: Thread:%p, type:%s, 
length:%i\n",
-                                                selector_store, g_thread_self (), list_type_string[type], 
g_list_length (list)););
+                       DEBUG_SELECTOR (g_print ("\tStore(%p): update_list_cb: type:%s, length:%i\n",
+                                                selector_store, list_type_string[type], g_list_length 
(list)););
 
-                       G_UNLOCK (store_recent_items_lock);
                        break;
                default:
                        break;
@@ -578,6 +576,11 @@ gedit_open_document_selector_store_dispose (GObject *object)
 
        gedit_recent_configuration_destroy (&selector_store->recent_config);
 
+       if (selector_store->recent_source != NULL)
+       {
+               g_clear_pointer (&selector_store->recent_source, g_source_destroy);
+       }
+
        if (selector_store->recent_items)
        {
                gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
@@ -610,63 +613,78 @@ static GList * (*list_func [])(GeditOpenDocumentSelectorStore *selector_store,
        get_current_docs_list
 };
 
-static void
-update_list_dispatcher (GTask        *task,
-                        gpointer      source_object,
-                        gpointer      task_data,
-                        GCancellable *cancellable)
+static gboolean
+update_recent_list (gpointer user_data)
 {
-       GeditOpenDocumentSelectorStore *selector_store = source_object;
+       GeditOpenDocumentSelectorStore *selector_store;
        GeditOpenDocumentSelector *selector;
        PushMessage *message;
        ListType type;
        GList *file_items_list;
+       GTask *task = G_TASK(user_data);
 
-       message = task_data;
+       selector_store = g_task_get_source_object (task);
+       message = g_task_get_task_data (task);
        selector = message->selector;
        type = message->type;
 
        DEBUG_SELECTOR_TIMER_DECL
        DEBUG_SELECTOR_TIMER_NEW
-       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s\n",
-                                selector, g_thread_self (), list_type_string[type]););
+       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s\n",
+                                selector, list_type_string[type]););
 
        /* Update the recent list only when it changes, copy otherwise but keep it the first time */
-       if (type == GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST)
+       if (selector_store->recent_items != NULL && selector_store->recent_items_need_update == FALSE)
        {
-               G_LOCK (store_recent_items_lock);
+               file_items_list = gedit_open_document_selector_copy_file_items_list 
(selector_store->recent_items);
 
-               if (selector_store->recent_items != NULL && selector_store->recent_items_need_update == FALSE)
-               {
-                       file_items_list = gedit_open_document_selector_copy_file_items_list 
(selector_store->recent_items);
+               DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list copy\n", selector););
+       }
+       else
+       {
+               selector_store->recent_items_need_update = FALSE;
+               file_items_list = get_recent_files_list (selector_store, selector);
 
-                       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list copy\n", 
selector););
-               }
-               else
+               DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list compute\n", selector););
+
+               if (selector_store->recent_items == NULL)
                {
-                       selector_store->recent_items_need_update = FALSE;
-                       file_items_list = get_recent_files_list (selector_store, selector);
+                       selector_store->recent_items = gedit_open_document_selector_copy_file_items_list 
(file_items_list);
+               }
+       }
 
-                       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list compute\n", 
selector););
+       g_task_return_pointer (task,
+                              file_items_list,
+                              (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
 
-                       if (selector_store->recent_items == NULL)
-                       {
-                               selector_store->recent_items = 
gedit_open_document_selector_copy_file_items_list (file_items_list);
-                       }
-               }
+       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s, time:%lf\n",
+                                selector, list_type_string[type], DEBUG_SELECTOR_TIMER_GET););
+       DEBUG_SELECTOR_TIMER_DESTROY
 
-               G_UNLOCK (store_recent_items_lock);
+        selector_store->recent_source = NULL;
+       return G_SOURCE_REMOVE;
+}
 
-               g_task_return_pointer (task,
-                                      file_items_list,
-                                      (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
+static void
+update_list_dispatcher (GTask        *task,
+                        gpointer      source_object,
+                        gpointer      task_data,
+                        GCancellable *cancellable)
+{
+       GeditOpenDocumentSelectorStore *selector_store = source_object;
+       GeditOpenDocumentSelector *selector;
+       PushMessage *message;
+       ListType type;
+       GList *file_items_list;
 
-               DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s, time:%lf\n",
-                                        selector, g_thread_self (), list_type_string[type], 
DEBUG_SELECTOR_TIMER_GET););
-               DEBUG_SELECTOR_TIMER_DESTROY
+       message = task_data;
+       selector = message->selector;
+       type = message->type;
 
-               return;
-       }
+       DEBUG_SELECTOR_TIMER_DECL
+       DEBUG_SELECTOR_TIMER_NEW
+       DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s\n",
+                                selector, g_thread_self (), list_type_string[type]););
 
        if (type >= GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS)
        {
@@ -723,7 +741,17 @@ gedit_open_document_selector_store_update_list_async (GeditOpenDocumentSelectorS
        g_task_set_priority (task, G_PRIORITY_DEFAULT);
        g_task_set_task_data (task, message, (GDestroyNotify)g_free);
 
-       g_task_run_in_thread (task, update_list_dispatcher);
+       if (type == GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST &&
+           selector_store->recent_source == NULL)
+       {
+               selector_store->recent_source = g_idle_source_new ();
+               g_task_attach_source (task, selector_store->recent_source, update_recent_list);
+       }
+       else
+       {
+               g_task_run_in_thread (task, update_list_dispatcher);
+       }
+
        g_object_unref (task);
 }
 


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