[gtk: 20/40] icon theme: Actually don't block in gtk_icon_theme_choose_icon_async()



commit 56ec7488245a09e52aaad4386f78dc9d50fc2887
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Jan 29 16:42:35 2020 +0100

    icon theme: Actually don't block in gtk_icon_theme_choose_icon_async()
    
    If some other thread is lock the icon or icon theme locks they are likely
    to do so for a long time, doing i/o. So, switch to trylock() for the
    nonblocking part of _async(). This way we can return directly if the
    result is available, but do a thread otherwise, never blocking the
    calling (main) thread.

 gtk/gtkicontheme.c | 51 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 20 deletions(-)
---
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index df38491b10..e99cc8d92c 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -397,10 +397,6 @@ static IconSuffix suffix_from_name                      (const gchar      *name)
 static gboolean   icon_ensure_scale_and_texture__locked (GtkIcon          *icon);
 static void       unset_display                         (GtkIconTheme     *self);
 static void       update_current_theme__mainthread      (GtkIconTheme     *self);
-static void       load_icon_thread                      (GTask            *task,
-                                                         gpointer          source_object,
-                                                         gpointer          task_data,
-                                                         GCancellable     *cancellable);
 static gboolean   ensure_valid_themes                   (GtkIconTheme     *self,
                                                          gboolean          non_blocking);
 
@@ -487,6 +483,12 @@ gtk_icon_theme_lock (GtkIconTheme *self)
   g_mutex_lock (&self->ref->lock);
 }
 
+static gboolean
+gtk_icon_theme_trylock (GtkIconTheme *self)
+{
+  return g_mutex_trylock (&self->ref->lock);
+}
+
 static void
 gtk_icon_theme_unlock (GtkIconTheme *self)
 {
@@ -2414,7 +2416,7 @@ gtk_icon_theme_choose_icon_async (GtkIconTheme       *self,
                                   gpointer             user_data)
 {
   GTask *task;
-  GtkIcon *icon;
+  GtkIcon *icon = NULL;
   gboolean would_block = FALSE;
 
   g_return_if_fail (GTK_IS_ICON_THEME (self));
@@ -2425,9 +2427,14 @@ gtk_icon_theme_choose_icon_async (GtkIconTheme       *self,
 
   task = g_task_new (self, cancellable, callback, user_data);
 
-  gtk_icon_theme_lock (self);
+  if (gtk_icon_theme_trylock (self))
+    {
+      icon = choose_icon (self, icon_names, size, 1, flags, TRUE, &would_block);
+      gtk_icon_theme_unlock (self);
+    }
+  else
+    would_block = TRUE;
 
-  icon = choose_icon (self, icon_names, size, 1, flags, TRUE, &would_block);
   if (icon == NULL)
     {
       if (would_block)
@@ -2443,27 +2450,31 @@ gtk_icon_theme_choose_icon_async (GtkIconTheme       *self,
                                    _("Icon not present in theme %s"), self->current_theme);
         }
     }
-
-  gtk_icon_theme_unlock (self);
-
-  if (icon)
+  else
     {
-      g_mutex_lock (&icon->texture_lock);
-
-      if (icon->texture)
-        g_task_return_pointer (task, icon, g_object_unref);
-      else if (icon->load_error)
+      gboolean done = FALSE;
+      if (g_mutex_trylock (&icon->texture_lock))
         {
-          g_task_return_error (task, g_error_copy (icon->load_error));
-          g_object_unref (icon);
+          if (icon->texture)
+            {
+              done = TRUE;
+              g_task_return_pointer (task, icon, g_object_unref);
+            }
+          else if (icon->load_error)
+            {
+              done = TRUE;
+              g_task_return_error (task, g_error_copy (icon->load_error));
+              g_object_unref (icon);
+            }
+          g_mutex_unlock (&icon->texture_lock);
         }
-      else
+
+      if (!done)
         {
           /* Not here, load it in a thread */
           g_task_set_task_data (task, icon, g_object_unref);
           g_task_run_in_thread (task, load_icon_thread);
         }
-      g_mutex_unlock (&icon->texture_lock);
     }
 }
 


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