[gtk: 20/40] icon theme: Actually don't block in gtk_icon_theme_choose_icon_async()
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 20/40] icon theme: Actually don't block in gtk_icon_theme_choose_icon_async()
- Date: Thu, 30 Jan 2020 17:32:49 +0000 (UTC)
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]