[gnome-software: 1/2] GsApp: Add thread safety around remote icons download
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 1/2] GsApp: Add thread safety around remote icons download
- Date: Fri, 26 Mar 2021 12:30:40 +0000 (UTC)
commit f05f68c651d22db8d1b5031ce0d656f4f073b556
Author: Milan Crha <mcrha redhat com>
Date: Fri Mar 26 12:30:39 2021 +0000
GsApp: Add thread safety around remote icons download
Hold a GsApp lock when ensuring remote application icons are cached
locally, to avoid race condition when it's done from multiple threads
for the same application.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1196
lib/gs-app.c | 52 ++++++++++++++++++++++++++++++++++++++++++
lib/gs-app.h | 5 ++++
plugins/core/gs-plugin-icons.c | 24 +------------------
3 files changed, 58 insertions(+), 23 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 12ee9a292..8eeaef836 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -48,6 +48,7 @@
#include "gs-key-colors.h"
#include "gs-os-release.h"
#include "gs-plugin.h"
+#include "gs-remote-icon.h"
#include "gs-utils.h"
typedef struct
@@ -5357,3 +5358,54 @@ gs_app_set_version_history (GsApp *app, GPtrArray *version_history)
locker = g_mutex_locker_new (&priv->mutex);
_g_set_ptr_array (&priv->version_history, version_history);
}
+
+/**
+ * gs_app_ensure_icons_downloaded:
+ * @app: a #GsApp
+ * @soup_session: a #SoupSession
+ * @maximum_icon_size: maximum icon size
+ * @cancellable: (nullable): optional #GCancellable object
+ *
+ * Ensure all remote icons in the @app's icons are locally cached.
+ *
+ * Since: 41
+ **/
+void
+gs_app_ensure_icons_downloaded (GsApp *app,
+ SoupSession *soup_session,
+ guint maximum_icon_size,
+ GCancellable *cancellable)
+{
+ GsAppPrivate *priv;
+ g_autoptr(GMutexLocker) locker = NULL;
+ GPtrArray *icons;
+ guint i;
+
+ g_return_if_fail (GS_IS_APP (app));
+
+ priv = gs_app_get_instance_private (app);
+ locker = g_mutex_locker_new (&priv->mutex);
+
+ /* process all icons */
+ icons = priv->icons;
+
+ for (i = 0; icons != NULL && i < icons->len; i++) {
+ GIcon *icon = g_ptr_array_index (icons, i);
+ g_autoptr(GError) error_local = NULL;
+
+ /* Only remote icons need to be cached. */
+ if (!GS_IS_REMOTE_ICON (icon))
+ continue;
+
+ if (!gs_remote_icon_ensure_cached (GS_REMOTE_ICON (icon),
+ soup_session,
+ maximum_icon_size,
+ cancellable,
+ &error_local)) {
+ /* we failed, but keep going */
+ g_debug ("failed to cache icon for %s: %s",
+ gs_app_get_id (app),
+ error_local->message);
+ }
+ }
+}
diff --git a/lib/gs-app.h b/lib/gs-app.h
index 3136b639f..2961da4b4 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -12,6 +12,7 @@
#include <glib-object.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libsoup/soup.h>
#include <appstream.h>
G_BEGIN_DECLS
@@ -471,5 +472,9 @@ void gs_app_set_update_permissions (GsApp *app,
GPtrArray *gs_app_get_version_history (GsApp *app);
void gs_app_set_version_history (GsApp *app,
GPtrArray *version_history);
+void gs_app_ensure_icons_downloaded (GsApp *app,
+ SoupSession *soup_session,
+ guint maximum_icon_size,
+ GCancellable *cancellable);
G_END_DECLS
diff --git a/plugins/core/gs-plugin-icons.c b/plugins/core/gs-plugin-icons.c
index 34bf52442..918c7d1e9 100644
--- a/plugins/core/gs-plugin-icons.c
+++ b/plugins/core/gs-plugin-icons.c
@@ -45,8 +45,6 @@ refine_app (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
- GPtrArray *icons;
- guint i;
SoupSession *soup_session;
guint maximum_icon_size;
@@ -59,27 +57,7 @@ refine_app (GsPlugin *plugin,
/* Currently a 160px icon is needed for #GsFeatureTile, at most. */
maximum_icon_size = 160 * gs_plugin_get_scale (plugin);
- /* process all icons */
- icons = gs_app_get_icons (app);
- for (i = 0; icons != NULL && i < icons->len; i++) {
- GIcon *icon = g_ptr_array_index (icons, i);
- g_autoptr(GError) error_local = NULL;
-
- /* Only remote icons need to be cached. */
- if (!GS_IS_REMOTE_ICON (icon))
- continue;
-
- if (!gs_remote_icon_ensure_cached (GS_REMOTE_ICON (icon),
- soup_session,
- maximum_icon_size,
- cancellable,
- &error_local)) {
- /* we failed, but keep going */
- g_debug ("failed to cache icon for %s: %s",
- gs_app_get_id (app),
- error_local->message);
- }
- }
+ gs_app_ensure_icons_downloaded (app, soup_session, maximum_icon_size, cancellable);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]