[gnome-software/jrocha/fix-install-queue: 1/3] Do not use queued apps (for installations) internally as GsApps



commit 59d9b8e21d0f4ee785e88be3b9d3aebee1855946
Author: Joaquim Rocha <jrocha endlessm com>
Date:   Fri Feb 16 12:52:52 2018 +0100

    Do not use queued apps (for installations) internally as GsApps
    
    If GsApp objects used for storing the apps queued for installation are
    used, then they may get created by the plugin loader (before the plugins
    create them) which will result in apps getting to a state where they
    will not be correctly refined (by not having the keys/metadata some
    plugins expect).
    
    For that reason, and for simplicity purposes, this patch makes the
    pending apps list as a simple array of unique IDs. This way we can
    simply return the globally cached (and correctly created) apps when
    using gs_plugin_loader_get_pending.

 lib/gs-plugin-loader.c | 80 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 27 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index d98a982f..a0cda68a 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -1677,6 +1677,28 @@ emit_pending_apps_idle (gpointer loader)
        return G_SOURCE_REMOVE;
 }
 
+static gint
+get_pending_app_index (GsPluginLoader *plugin_loader,
+                      const gchar *app_id)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       for (guint i = 0; i < priv->pending_apps->len; ++i) {
+               const gchar *id = g_ptr_array_index (priv->pending_apps, i);
+               if (g_strcmp0 (id, app_id) == 0)
+                       return i;
+       }
+       return -1;
+}
+
+static void
+add_pending_app (GsPluginLoader *plugin_loader,
+                const gchar *app_id)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       if (get_pending_app_index (plugin_loader, app_id) == -1)
+               g_ptr_array_add (priv->pending_apps, g_strdup (app_id));
+}
+
 static void
 gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader,
                                   GsPluginLoaderHelper *helper)
@@ -1688,13 +1710,27 @@ gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader,
        g_assert (gs_app_list_length (list) > 0);
        for (guint i = 0; i < gs_app_list_length (list); i++) {
                GsApp *app = gs_app_list_index (list, i);
-               g_ptr_array_add (priv->pending_apps, g_object_ref (app));
+               add_pending_app (plugin_loader, gs_app_get_unique_id (app));
                /* make sure the progress is properly initialized */
                gs_app_set_progress (app, 0);
        }
        g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader));
 }
 
+static gboolean
+remove_pending_app (GsPluginLoader *plugin_loader,
+                   const gchar *app_id)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       gint index = get_pending_app_index (plugin_loader, app_id);
+
+       if (index != -1) {
+               g_ptr_array_remove_index (priv->pending_apps, index);
+               return TRUE;
+       }
+       return FALSE;
+}
+
 static void
 gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader,
                                      GsPluginLoaderHelper *helper)
@@ -1706,7 +1742,7 @@ gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader,
        g_assert (gs_app_list_length (list) > 0);
        for (guint i = 0; i < gs_app_list_length (list); i++) {
                GsApp *app = gs_app_list_index (list, i);
-               g_ptr_array_remove (priv->pending_apps, app);
+               remove_pending_app (plugin_loader, gs_app_get_unique_id (app));
 
                /* check the app is not still in an action helper */
                switch (gs_app_get_state (app)) {
@@ -1768,21 +1804,10 @@ load_install_queue (GsPluginLoader *plugin_loader, GError **error)
        for (guint i = 0; i < gs_app_list_length (list); i++) {
                GsApp *app = gs_app_list_index (list, i);
                g_debug ("adding pending app %s", gs_app_get_unique_id (app));
-               g_ptr_array_add (priv->pending_apps, g_object_ref (app));
+               add_pending_app (plugin_loader, gs_app_get_unique_id (app));
        }
        g_mutex_unlock (&priv->pending_apps_mutex);
 
-       /* refine */
-       if (gs_app_list_length (list) > 0) {
-               g_autoptr(GsPluginLoaderHelper) helper = NULL;
-               g_autoptr(GsPluginJob) plugin_job = NULL;
-               plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, NULL);
-               helper = gs_plugin_loader_helper_new (plugin_loader, plugin_job);
-               gs_plugin_job_set_failure_flags (helper->plugin_job,
-                                                GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS);
-               if (!gs_plugin_loader_run_refine (helper, list, NULL, error))
-                       return FALSE;
-       }
        return TRUE;
 }
 
@@ -1801,12 +1826,9 @@ save_install_queue (GsPluginLoader *plugin_loader)
        pending_apps = priv->pending_apps;
        g_mutex_lock (&priv->pending_apps_mutex);
        for (i = (gint) pending_apps->len - 1; i >= 0; i--) {
-               GsApp *app;
-               app = g_ptr_array_index (pending_apps, i);
-               if (gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL) {
-                       g_string_append (s, gs_app_get_unique_id (app));
-                       g_string_append_c (s, '\n');
-               }
+               const gchar *id = g_ptr_array_index (pending_apps, i);
+               g_string_append (s, id);
+               g_string_append_c (s, '\n');
        }
        g_mutex_unlock (&priv->pending_apps_mutex);
 
@@ -1833,10 +1855,11 @@ add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app)
        GPtrArray *addons;
        guint i;
        guint id;
+       const gchar *app_id = gs_app_get_unique_id (app);
 
        /* queue the app itself */
        g_mutex_lock (&priv->pending_apps_mutex);
-       g_ptr_array_add (priv->pending_apps, g_object_ref (app));
+       add_pending_app (plugin_loader, app_id);
        g_mutex_unlock (&priv->pending_apps_mutex);
 
        gs_app_set_state (app, AS_APP_STATE_QUEUED_FOR_INSTALL);
@@ -1863,7 +1886,7 @@ remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app)
        guint id;
 
        g_mutex_lock (&priv->pending_apps_mutex);
-       ret = g_ptr_array_remove (priv->pending_apps, app);
+       ret = remove_pending_app (plugin_loader, gs_app_get_unique_id (app));
        g_mutex_unlock (&priv->pending_apps_mutex);
 
        if (ret) {
@@ -1915,8 +1938,10 @@ gs_plugin_loader_get_pending (GsPluginLoader *plugin_loader)
        array = gs_app_list_new ();
        g_mutex_lock (&priv->pending_apps_mutex);
        for (i = 0; i < priv->pending_apps->len; i++) {
-               GsApp *app = g_ptr_array_index (priv->pending_apps, i);
-               gs_app_list_add (array, app);
+               const gchar *id = g_ptr_array_index (priv->pending_apps, i);
+               GsApp *app = gs_app_list_lookup (priv->global_cache, id);
+               if (app != NULL)
+                       gs_app_list_add (array, app);
        }
        g_mutex_unlock (&priv->pending_apps_mutex);
 
@@ -2832,7 +2857,7 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        priv->scale = 1;
        priv->global_cache = gs_app_list_new ();
        priv->plugins = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
-       priv->pending_apps = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
+       priv->pending_apps = g_ptr_array_new_with_free_func (g_free);
        priv->queued_ops_pool = g_thread_pool_new (gs_plugin_loader_process_in_thread_pool_cb,
                                                   NULL,
                                                   get_max_parallel_ops (),
@@ -2973,8 +2998,9 @@ gs_plugin_loader_network_changed_cb (GNetworkMonitor *monitor,
                g_mutex_lock (&priv->pending_apps_mutex);
                queue = gs_app_list_new ();
                for (guint i = 0; i < priv->pending_apps->len; i++) {
-                       GsApp *app = g_ptr_array_index (priv->pending_apps, i);
-                       if (gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL)
+                       const gchar *id = g_ptr_array_index (priv->pending_apps, i);
+                       GsApp *app = gs_app_list_lookup (priv->global_cache, id);
+                       if (app != NULL && gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL)
                                gs_app_list_add (queue, app);
                }
                g_mutex_unlock (&priv->pending_apps_mutex);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]