forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
1e6a82513b
commit
56ec748824
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user