plug-ins: try to load the gimp-help.xml file in a thread.

I had a case where the GIO API ended just stuck and never returning.
This API is made to work in a thread so that you can cancel loading URIs
from the main thread. Let's make use of that.
This commit is contained in:
Jehan 2025-02-20 17:54:08 +01:00
parent 87a22a7401
commit f2d47e910b
3 changed files with 74 additions and 10 deletions

View file

@ -42,8 +42,21 @@
#endif
typedef struct
{
gboolean *success;
GimpHelpLocale *locale;
const gchar *uri;
const gchar *domain;
GimpHelpProgress *progress;
GCancellable *cancellable;
GError **error;
} HelpThreadData;
/* local function prototypes */
static gboolean parse_thread_func (HelpThreadData *data);
static gboolean domain_locale_parse (GimpHelpDomain *domain,
GimpHelpLocale *locale,
GimpHelpProgress *progress,
@ -228,14 +241,34 @@ gimp_help_domain_map (GimpHelpDomain *domain,
/* private functions */
G_LOCK_DEFINE (success);
static gboolean
parse_thread_func (HelpThreadData *data)
{
gboolean success = FALSE;
success = gimp_help_locale_parse (data->locale, data->uri, data->domain,
data->progress, data->cancellable, data->error);
G_LOCK (success);
*data->success = success;
G_UNLOCK (success);
return success;
}
static gboolean
domain_locale_parse (GimpHelpDomain *domain,
GimpHelpLocale *locale,
GimpHelpProgress *progress,
GError **error)
{
gchar *uri;
gboolean success;
GCancellable *cancellable;
gchar *uri;
GThread *thread;
GTimer *timer;
gboolean success = FALSE;
HelpThreadData data;
g_return_val_if_fail (domain != NULL, FALSE);
g_return_val_if_fail (locale != NULL, FALSE);
@ -244,10 +277,40 @@ domain_locale_parse (GimpHelpDomain *domain,
uri = g_strdup_printf ("%s/%s/gimp-help.xml",
domain->help_uri, locale->locale_id);
success = gimp_help_locale_parse (locale, uri, domain->help_domain,
progress, error);
timer = g_timer_new ();
cancellable = g_cancellable_new ();
data.success = &success;
data.locale = locale;
data.uri = uri;
data.domain = domain->help_domain;
data.progress = progress;
data.cancellable = cancellable;
data.error = error;
thread = g_thread_new (NULL, (GThreadFunc) parse_thread_func, &data);
while (TRUE)
{
gboolean exit;
G_LOCK (success);
exit = success;
G_UNLOCK (success);
if (! exit && g_timer_elapsed (timer, NULL) > 10.0)
{
g_cancellable_cancel (cancellable);
exit = TRUE;
}
if (exit)
break;
}
g_thread_join (thread);
g_free (uri);
g_timer_destroy (timer);
g_object_unref (cancellable);
return success;
}

View file

@ -169,11 +169,11 @@ gimp_help_locale_parse (GimpHelpLocale *locale,
const gchar *uri,
const gchar *help_domain,
GimpHelpProgress *progress,
GCancellable *cancellable,
GError **error)
{
GMarkupParseContext *context;
GFile *file = NULL;
GCancellable *cancellable = NULL;
LocaleParser parser = { NULL, };
#ifdef PLATFORM_OSX
NSURL *fileURL;
@ -213,12 +213,12 @@ gimp_help_locale_parse (GimpHelpLocale *locale,
{
gchar *name = g_file_get_parse_name (file);
cancellable = g_cancellable_new ();
_gimp_help_progress_start (progress, cancellable,
_("Loading index from '%s'"), name);
g_clear_object (&cancellable);
g_free (name);
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
}
#ifdef PLATFORM_OSX
@ -249,7 +249,7 @@ gimp_help_locale_parse (GimpHelpLocale *locale,
GFileInfo *info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_SIZE, 0,
cancellable, error);
if (! info)
if (! info || g_cancellable_is_cancelled (cancellable))
{
locale_set_error (error,
_("Could not open '%s' for reading: %s"), file);
@ -265,7 +265,7 @@ gimp_help_locale_parse (GimpHelpLocale *locale,
stream = g_file_read (file, cancellable, error);
if (! stream)
if (! stream || g_cancellable_is_cancelled (cancellable))
{
locale_set_error (error,
_("Could not open '%s' for reading: %s"), file);
@ -307,7 +307,7 @@ gimp_help_locale_parse (GimpHelpLocale *locale,
g_string_free (parser.value, TRUE);
g_free (parser.id_attr_name);
if (! success)
if (! success || g_cancellable_is_cancelled (cancellable))
locale_set_error (error, _("Parse error in '%s':\n%s"), file);
g_object_unref (file);

View file

@ -45,6 +45,7 @@ gboolean gimp_help_locale_parse (GimpHelpLocale *locale,
const gchar *uri,
const gchar *help_domain,
GimpHelpProgress *progress,
GCancellable *cancellable,
GError **error);