From 8b13f8854a5125c073d5e8eba5b44c41d59ae4f3 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 5 Sep 2024 12:20:01 +0100 Subject: [PATCH] gresource: Remove unnecessary errors from g_resources_lookup_data() This is slightly more involved than the previous couple of commits, as `g_resource_lookup_data()` can return two errors: one if the resource is not found, and another if decompression fails. We want to avoid allocating the `G_RESOURCE_ERROR_NOT_FOUND` error, as `g_resources_lookup_data()` will be looping through multiple `GResource`s trying to find the given path, and all but one of them will return `G_RESOURCE_ERROR_NOT_FOUND`. For a large application, this can amount to a lot of `GError`s allocated and then immediately freed on startup. Use the split from the previous commit to replace the call to `g_resource_lookup_data()` with its two constituent parts. We can then handle errors from them separately, ignoring the `NOT_FOUND` error from `do_lookup()`, while paying attention to any errors from `resource_to_bytes()`. This should result in no functional difference to `g_resources_lookup_data()`, but fewer allocations overall. Spotted by Christian Hergert. Signed-off-by: Philip Withnall Helps: #3465 --- gio/gresource.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gio/gresource.c b/gio/gresource.c index b34c5bd24..53bf742d5 100644 --- a/gio/gresource.c +++ b/gio/gresource.c @@ -834,6 +834,10 @@ static GBytes *resource_to_bytes (GResource *resource, * * @lookup_flags controls the behaviour of the lookup. * + * This can return error %G_RESOURCE_ERROR_NOT_FOUND if @path was not found in + * @resource, or %G_RESOURCE_ERROR_INTERNAL if decompression of a compressed + * resource failed. + * * Returns: (transfer full): #GBytes or %NULL on error. * Free the returned object with g_bytes_unref() * @@ -1195,7 +1199,6 @@ g_resources_lookup_data (const gchar *path, { GBytes *res = NULL; GList *l; - GBytes *data; if (g_resource_find_overlay (path, get_overlay_bytes, &res)) return res; @@ -1207,19 +1210,16 @@ g_resources_lookup_data (const gchar *path, for (l = registered_resources; l != NULL; l = l->next) { GResource *r = l->data; - GError *my_error = NULL; + const void *data; + guint32 flags; + gsize data_size; + gsize size; - data = g_resource_lookup_data (r, path, lookup_flags, &my_error); - if (data == NULL && - g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + /* This is essentially g_resource_lookup_data(), but split up so we can + * avoid allocating a #GError if the resource is not found. */ + if (do_lookup (r, path, lookup_flags, &size, &flags, &data, &data_size, NULL)) { - g_clear_error (&my_error); - } - else - { - if (data == NULL) - g_propagate_error (error, my_error); - res = data; + res = resource_to_bytes (r, path, size, data, data_size, flags, error); break; } }