[gnome-software: 1/2] plugin-loader: Refine before installing pending apps
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 1/2] plugin-loader: Refine before installing pending apps
- Date: Thu, 29 Sep 2022 06:41:33 +0000 (UTC)
commit 0a51b0e5c73e249c6b4b959dfcbc785d394b287d
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Aug 29 13:50:24 2022 -0300
plugin-loader: Refine before installing pending apps
The installation of pending apps is handled by GsInstalledPage
usually, which refines the app list before actually installing
them. However, there is an alternative code path in GsPluginLoader
that doesn't refine, and yet tries to install the pending apps
queue.
Not refining the pending apps list is risky, since the Flatpak
plugin needs to add metadata to the app in order to proceed with
installation.
Refine the pending apps queue before installing it.
lib/gs-plugin-loader.c | 94 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 75 insertions(+), 19 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 63f741c37..8aa00882f 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -53,6 +53,7 @@ struct _GsPluginLoader
GMutex pending_apps_mutex;
GsAppList *pending_apps; /* (nullable) (owned) */
+ GCancellable *pending_apps_cancellable; /* (nullable) (owned) */
GThreadPool *queued_ops_pool;
gint active_jobs;
@@ -2535,6 +2536,8 @@ gs_plugin_loader_dispose (GObject *object)
{
GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
+ g_cancellable_cancel (plugin_loader->pending_apps_cancellable);
+
if (plugin_loader->plugins != NULL) {
/* Shut down all the plugins first. */
gs_plugin_loader_shutdown (plugin_loader, NULL);
@@ -2572,6 +2575,7 @@ gs_plugin_loader_dispose (GObject *object)
g_clear_object (&plugin_loader->category_manager);
g_clear_object (&plugin_loader->odrs_provider);
g_clear_object (&plugin_loader->setup_complete_cancellable);
+ g_clear_object (&plugin_loader->pending_apps_cancellable);
#ifdef HAVE_SYSPROF
g_clear_pointer (&plugin_loader->sysprof_writer, sysprof_capture_writer_unref);
@@ -2936,9 +2940,68 @@ gs_plugin_loader_get_network_metered (GsPluginLoader *plugin_loader)
return g_network_monitor_get_network_metered (plugin_loader->network_monitor);
}
+static void
+gs_plugin_loader_pending_apps_refined_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+ g_autoptr(GsAppList) old_queue = GS_APP_LIST (user_data);
+ g_autoptr(GsAppList) refined_queue = NULL;
+ g_autoptr(GError) error = NULL;
+
+ refined_queue = gs_plugin_loader_job_process_finish (plugin_loader, res, &error);
+
+ if (refined_queue == NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ !g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED)) {
+ g_debug ("failed to refine pending apps: %s", error->message);
+
+ g_mutex_lock (&plugin_loader->pending_apps_mutex);
+ g_clear_object (&plugin_loader->pending_apps);
+ g_mutex_unlock (&plugin_loader->pending_apps_mutex);
+
+ save_install_queue (plugin_loader);
+ }
+ return;
+ }
+
+ for (guint i = 0; i < gs_app_list_length (old_queue); i++) {
+ GsApp *app = gs_app_list_index (old_queue, i);
+
+ if (gs_app_list_lookup (refined_queue, gs_app_get_unique_id (app)) == NULL)
+ remove_app_from_install_queue (plugin_loader, app);
+ }
+
+ for (guint i = 0; i < gs_app_list_length (refined_queue); i++) {
+ GsApp *app = gs_app_list_index (refined_queue, i);
+ g_autoptr(GsPluginJob) plugin_job = NULL;
+
+ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) {
+ plugin_job = gs_plugin_job_manage_repository_new (app,
+
GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE |
+
GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INSTALL);
+ } else {
+ /* The 'interactive' is needed for credentials prompt, otherwise it just fails */
+ plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL,
+ "app", app,
+ "interactive", TRUE,
+ NULL);
+ }
+
+ gs_plugin_loader_job_process_async (plugin_loader, plugin_job,
+ gs_app_get_cancellable (app),
+ gs_plugin_loader_app_installed_cb,
+ g_object_ref (app));
+ }
+
+ g_clear_object (&plugin_loader->pending_apps_cancellable);
+}
+
static void
gs_plugin_loader_maybe_flush_pending_install_queue (GsPluginLoader *plugin_loader)
{
+ g_autoptr(GsPluginJob) plugin_job = NULL;
g_autoptr(GsAppList) obsolete = NULL;
g_autoptr(GsAppList) queue = NULL;
@@ -2955,6 +3018,10 @@ gs_plugin_loader_maybe_flush_pending_install_queue (GsPluginLoader *plugin_loade
return;
}
+ /* Already flushing pending queue */
+ if (plugin_loader->pending_apps_cancellable)
+ return;
+
queue = gs_app_list_new ();
obsolete = gs_app_list_new ();
g_mutex_lock (&plugin_loader->pending_apps_mutex);
@@ -2972,25 +3039,14 @@ gs_plugin_loader_maybe_flush_pending_install_queue (GsPluginLoader *plugin_loade
GsApp *app = gs_app_list_index (obsolete, i);
remove_app_from_install_queue (plugin_loader, app);
}
- for (guint i = 0; i < gs_app_list_length (queue); i++) {
- GsApp *app = gs_app_list_index (queue, i);
- g_autoptr(GsPluginJob) plugin_job = NULL;
- /* The 'interactive' is needed for credentials prompt, otherwise it just fails */
- if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) {
- plugin_job = gs_plugin_job_manage_repository_new (app,
-
GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE |
-
GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INSTALL);
- } else {
- plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL,
- "app", app,
- "interactive", TRUE,
- NULL);
- }
- gs_plugin_loader_job_process_async (plugin_loader, plugin_job,
- gs_app_get_cancellable (app),
- gs_plugin_loader_app_installed_cb,
- g_object_ref (app));
- }
+
+ plugin_loader->pending_apps_cancellable = g_cancellable_new ();
+
+ plugin_job = gs_plugin_job_refine_new (queue, GS_PLUGIN_REFINE_FLAGS_NONE);
+ gs_plugin_loader_job_process_async (plugin_loader, plugin_job,
+ plugin_loader->pending_apps_cancellable,
+ gs_plugin_loader_pending_apps_refined_cb,
+ g_steal_pointer (&queue));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]