[gnome-software: 2/3] gs-app: Make list of addons immutable
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 2/3] gs-app: Make list of addons immutable
- Date: Fri, 29 Apr 2022 09:27:06 +0000 (UTC)
commit 8ece9b796541c6568717e6e84898389435fc8c37
Author: Philip Withnall <pwithnall endlessos org>
Date: Wed Apr 13 15:56:05 2022 +0100
gs-app: Make list of addons immutable
Change `gs_app_add_addons()` to use the read-copy-update approach, so
that any lists of addons returned by previous calls to
`gs_app_dup_addons()` are not modified.
While we’re at it, make it operate on a list of addons, rather than a
single addon, which should reduce the number of read-copy-update cycles
needed in `gs-appstream.c`.
Finally, avoid allocating an internal list of addons in a `GsApp` until
the first addon is added. This should avoid carrying an empty allocated
`GsAppList` around in various apps which will never have addons. It
should save a small amount of memory.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
Fixes: #1721
lib/gs-app.c | 31 ++++++++++++++++++++++---------
lib/gs-app.h | 5 +++--
lib/gs-appstream.c | 17 +++++++++++++----
lib/gs-self-test.c | 9 ++++++---
4 files changed, 44 insertions(+), 18 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 52153c3e9..efbdb5eed 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -3886,25 +3886,37 @@ gs_app_dup_addons (GsApp *app)
}
/**
- * gs_app_add_addon:
+ * gs_app_add_addons:
* @app: a #GsApp
- * @addon: a #GsApp
+ * @addons: (transfer none) (not nullable): a list of #GsApps
*
- * Adds an addon to the list of application addons.
+ * Adds zero or more addons to the list of application addons.
*
- * Since: 3.22
+ * Since: 43
**/
void
-gs_app_add_addon (GsApp *app, GsApp *addon)
+gs_app_add_addons (GsApp *app,
+ GsAppList *addons)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_autoptr(GMutexLocker) locker = NULL;
+ g_autoptr(GsAppList) new_addons = NULL;
g_return_if_fail (GS_IS_APP (app));
- g_return_if_fail (GS_IS_APP (addon));
+ g_return_if_fail (GS_IS_APP_LIST (addons));
+
+ if (gs_app_list_length (addons) == 0)
+ return;
locker = g_mutex_locker_new (&priv->mutex);
- gs_app_list_add (priv->addons, addon);
+
+ if (priv->addons != NULL)
+ new_addons = gs_app_list_copy (priv->addons);
+ else
+ new_addons = gs_app_list_new ();
+ gs_app_list_add_list (new_addons, addons);
+
+ g_set_object (&priv->addons, new_addons);
}
/**
@@ -3924,7 +3936,9 @@ gs_app_remove_addon (GsApp *app, GsApp *addon)
g_return_if_fail (GS_IS_APP (app));
g_return_if_fail (GS_IS_APP (addon));
locker = g_mutex_locker_new (&priv->mutex);
- gs_app_list_remove (priv->addons, addon);
+
+ if (priv->addons != NULL)
+ gs_app_list_remove (priv->addons, addon);
}
/**
@@ -5586,7 +5600,6 @@ gs_app_init (GsApp *app)
priv->sources = g_ptr_array_new_with_free_func (g_free);
priv->source_ids = g_ptr_array_new_with_free_func (g_free);
priv->categories = g_ptr_array_new_with_free_func (g_free);
- priv->addons = gs_app_list_new ();
priv->related = gs_app_list_new ();
priv->history = gs_app_list_new ();
priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
diff --git a/lib/gs-app.h b/lib/gs-app.h
index 325dfd86d..1fa75b266 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -19,6 +19,7 @@ G_BEGIN_DECLS
/* Dependency loop means we can’t include the header. */
typedef struct _GsPlugin GsPlugin;
+typedef struct _GsAppList GsAppList;
#define GS_TYPE_APP (gs_app_get_type ())
@@ -428,8 +429,8 @@ guint64 gs_app_get_size_download_dependencies
(GsApp *app);
void gs_app_add_related (GsApp *app,
GsApp *app2);
-void gs_app_add_addon (GsApp *app,
- GsApp *addon);
+void gs_app_add_addons (GsApp *app,
+ GsAppList *addons);
void gs_app_add_history (GsApp *app,
GsApp *app2);
guint64 gs_app_get_install_date (GsApp *app);
diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c
index b0aea1f3e..cdaa86e5c 100644
--- a/lib/gs-appstream.c
+++ b/lib/gs-appstream.c
@@ -290,6 +290,7 @@ gs_appstream_refine_add_addons (GsPlugin *plugin,
g_autofree gchar *xpath = NULL;
g_autoptr(GError) error_local = NULL;
g_autoptr(GPtrArray) addons = NULL;
+ g_autoptr(GsAppList) addons_list = NULL;
/* get all components */
xpath = g_strdup_printf ("components/component/extends[text()='%s']/..",
@@ -303,14 +304,22 @@ gs_appstream_refine_add_addons (GsPlugin *plugin,
g_propagate_error (error, g_steal_pointer (&error_local));
return FALSE;
}
+
+ addons_list = gs_app_list_new ();
+
for (guint i = 0; i < addons->len; i++) {
XbNode *addon = g_ptr_array_index (addons, i);
- g_autoptr(GsApp) app2 = NULL;
- app2 = gs_appstream_create_app (plugin, silo, addon, error);
- if (app2 == NULL)
+ g_autoptr(GsApp) addon_app = NULL;
+
+ addon_app = gs_appstream_create_app (plugin, silo, addon, error);
+ if (addon_app == NULL)
return FALSE;
- gs_app_add_addon (app, app2);
+
+ gs_app_list_add (addons_list, addon_app);
}
+
+ gs_app_add_addons (app, addons_list);
+
return TRUE;
}
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index 9a75d5b12..24dddd061 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -564,12 +564,15 @@ static void
gs_app_addons_func (void)
{
g_autoptr(GsApp) app = gs_app_new ("test.desktop");
- GsApp *addon;
+ g_autoptr(GsApp) addon = NULL;
+ g_autoptr(GsAppList) addons_list = NULL;
/* create, add then drop ref, so @app has the only refcount of addon */
addon = gs_app_new ("test.desktop");
- gs_app_add_addon (app, addon);
- g_object_unref (addon);
+ addons_list = gs_app_list_new ();
+ gs_app_list_add (addons_list, addon);
+
+ gs_app_add_addons (app, addons_list);
gs_app_remove_addon (app, addon);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]