[gnome-software/wip/rancell/ubuntu-ratings] packagekit plugins: Fix AsProfile use from multiple threads



commit 4204a6c52598e026f2aff800cb13ca02d9e7af55
Author: Kalev Lember <klember redhat com>
Date:   Mon Oct 19 15:01:20 2015 +0200

    packagekit plugins: Fix AsProfile use from multiple threads
    
    Move AsProfile state keeping to a helper struct, instead of keeping it
    in a plugin private data. As the plugins can be used from multiple
    threads simultaneously, we can't use global private data for storing
    state during long sync calls, as another thread may overwrite (or double
    free) first thread's state.
    
    This fixes suprious profile dumps we've been seeing with new AsProfile
    code.

 src/plugins/gs-plugin-packagekit-refine.c  |   43 ++++++++++++++++++++++------
 src/plugins/gs-plugin-packagekit-refresh.c |   32 +++++++++++++++------
 2 files changed, 57 insertions(+), 18 deletions(-)
---
diff --git a/src/plugins/gs-plugin-packagekit-refine.c b/src/plugins/gs-plugin-packagekit-refine.c
index a6f3fa4..126a594 100644
--- a/src/plugins/gs-plugin-packagekit-refine.c
+++ b/src/plugins/gs-plugin-packagekit-refine.c
@@ -101,6 +101,12 @@ gs_plugin_destroy (GsPlugin *plugin)
        g_object_unref (plugin->priv->control);
 }
 
+
+typedef struct {
+       GsPlugin        *plugin;
+       AsProfileTask   *ptask;
+} ProgressData;
+
 /**
  * gs_plugin_packagekit_progress_cb:
  **/
@@ -109,9 +115,10 @@ gs_plugin_packagekit_progress_cb (PkProgress *progress,
                                  PkProgressType type,
                                  gpointer user_data)
 {
+       ProgressData *data = (ProgressData *) user_data;
+       GsPlugin *plugin = data->plugin;
        GsPluginStatus plugin_status;
        PkStatusEnum status;
-       GsPlugin *plugin = GS_PLUGIN (user_data);
 
        if (type != PK_PROGRESS_TYPE_STATUS)
                return;
@@ -121,10 +128,10 @@ gs_plugin_packagekit_progress_cb (PkProgress *progress,
 
        /* profile */
        if (status == PK_STATUS_ENUM_SETUP) {
-               plugin->priv->ptask = as_profile_start_literal (plugin->profile,
+               data->ptask = as_profile_start_literal (plugin->profile,
                                                                "packagekit-refine::transaction");
        } else if (status == PK_STATUS_ENUM_FINISHED) {
-               g_clear_pointer (&plugin->priv->ptask, as_profile_task_free);
+               g_clear_pointer (&data->ptask, as_profile_task_free);
        }
 
        plugin_status = packagekit_status_enum_to_plugin_status (status);
@@ -269,6 +276,7 @@ gs_plugin_packagekit_resolve_packages (GsPlugin *plugin,
        GsApp *app;
        const gchar *pkgname;
        guint i;
+       ProgressData data;
        g_autoptr(PkError) error_code = NULL;
        g_autoptr(PkResults) results = NULL;
        g_autoptr(GPtrArray) package_ids = NULL;
@@ -285,12 +293,14 @@ gs_plugin_packagekit_resolve_packages (GsPlugin *plugin,
        }
        g_ptr_array_add (package_ids, NULL);
 
+       data.plugin = plugin;
+
        /* resolve them all at once */
        results = pk_client_resolve (plugin->priv->client,
                                     pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_ARCH, -1),
                                     (gchar **) package_ids->pdata,
                                     cancellable,
-                                    gs_plugin_packagekit_progress_cb, plugin,
+                                    gs_plugin_packagekit_progress_cb, &data,
                                     error);
        if (results == NULL)
                return FALSE;
@@ -326,16 +336,19 @@ gs_plugin_packagekit_refine_from_desktop (GsPlugin *plugin,
                                          GError **error)
 {
        const gchar *to_array[] = { NULL, NULL };
+       ProgressData data;
        g_autoptr(PkError) error_code = NULL;
        g_autoptr(PkResults) results = NULL;
        g_autoptr(GPtrArray) packages = NULL;
 
+       data.plugin = plugin;
+
        to_array[0] = filename;
        results = pk_client_search_files (plugin->priv->client,
                                          pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, -1),
                                          (gchar **) to_array,
                                          cancellable,
-                                         gs_plugin_packagekit_progress_cb, plugin,
+                                         gs_plugin_packagekit_progress_cb, &data,
                                          error);
        if (results == NULL)
                return FALSE;
@@ -380,6 +393,7 @@ gs_plugin_packagekit_refine_updatedetails (GsPlugin *plugin,
        guint i = 0;
        guint size;
        PkUpdateDetail *update_detail;
+       ProgressData data;
        g_autofree const gchar **package_ids = NULL;
        g_autoptr(PkResults) results = NULL;
        g_autoptr(GPtrArray) array = NULL;
@@ -392,11 +406,13 @@ gs_plugin_packagekit_refine_updatedetails (GsPlugin *plugin,
                package_ids[i++] = package_id;
        }
 
+       data.plugin = plugin;
+
        /* get any update details */
        results = pk_client_get_update_detail (plugin->priv->client,
                                               (gchar **) package_ids,
                                               cancellable,
-                                              gs_plugin_packagekit_progress_cb, plugin,
+                                              gs_plugin_packagekit_progress_cb, &data,
                                               error);
        if (results == NULL)
                return FALSE;
@@ -518,6 +534,7 @@ gs_plugin_packagekit_refine_details (GsPlugin *plugin,
        GsApp *app;
        const gchar *package_id;
        guint i;
+       ProgressData data;
        g_autoptr(GPtrArray) array = NULL;
        g_autoptr(GPtrArray) package_ids = NULL;
        g_autoptr(PkResults) results = NULL;
@@ -533,11 +550,13 @@ gs_plugin_packagekit_refine_details (GsPlugin *plugin,
        }
        g_ptr_array_add (package_ids, NULL);
 
+       data.plugin = plugin;
+
        /* get any details */
        results = pk_client_get_details (plugin->priv->client,
                                         (gchar **) package_ids->pdata,
                                         cancellable,
-                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        gs_plugin_packagekit_progress_cb, &data,
                                         error);
        if (results == NULL)
                return FALSE;
@@ -564,15 +583,18 @@ gs_plugin_packagekit_refine_update_severity (GsPlugin *plugin,
        GsApp *app;
        const gchar *package_id;
        PkBitfield filter;
+       ProgressData data;
        g_autoptr(PkPackageSack) sack = NULL;
        g_autoptr(PkResults) results = NULL;
 
+       data.plugin = plugin;
+
        /* get the list of updates */
        filter = pk_bitfield_value (PK_FILTER_ENUM_NONE);
        results = pk_client_get_updates (plugin->priv->client,
                                         filter,
                                         cancellable,
-                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        gs_plugin_packagekit_progress_cb, &data,
                                         error);
        if (results == NULL)
                return FALSE;
@@ -675,15 +697,18 @@ gs_plugin_packagekit_get_source_list (GsPlugin *plugin,
                                      GError **error)
 {
        PkRepoDetail *rd;
+       ProgressData data;
        guint i;
        g_autoptr(PkResults) results = NULL;
        g_autoptr(GPtrArray) array = NULL;
 
+       data.plugin = plugin;
+
        /* ask PK for the repo details */
        results = pk_client_get_repo_list (plugin->priv->client,
                                           pk_bitfield_from_enums (PK_FILTER_ENUM_NONE, -1),
                                           cancellable,
-                                          gs_plugin_packagekit_progress_cb, plugin,
+                                          gs_plugin_packagekit_progress_cb, &data,
                                           error);
        if (results == NULL)
                return FALSE;
diff --git a/src/plugins/gs-plugin-packagekit-refresh.c b/src/plugins/gs-plugin-packagekit-refresh.c
index 7212db7..8acda0d 100644
--- a/src/plugins/gs-plugin-packagekit-refresh.c
+++ b/src/plugins/gs-plugin-packagekit-refresh.c
@@ -31,7 +31,6 @@
 
 struct GsPluginPrivate {
        PkTask                  *task;
-       AsProfileTask           *ptask;
 };
 
 /**
@@ -64,6 +63,11 @@ gs_plugin_destroy (GsPlugin *plugin)
        g_object_unref (plugin->priv->task);
 }
 
+typedef struct {
+       GsPlugin        *plugin;
+       AsProfileTask   *ptask;
+} ProgressData;
+
 /**
  * gs_plugin_packagekit_progress_cb:
  **/
@@ -72,9 +76,10 @@ gs_plugin_packagekit_progress_cb (PkProgress *progress,
                                  PkProgressType type,
                                  gpointer user_data)
 {
+       ProgressData *data = (ProgressData *) user_data;
+       GsPlugin *plugin = data->plugin;
        GsPluginStatus plugin_status;
        PkStatusEnum status;
-       GsPlugin *plugin = GS_PLUGIN (user_data);
 
        if (type != PK_PROGRESS_TYPE_STATUS)
                return;
@@ -84,10 +89,10 @@ gs_plugin_packagekit_progress_cb (PkProgress *progress,
 
        /* profile */
        if (status == PK_STATUS_ENUM_SETUP) {
-               plugin->priv->ptask = as_profile_start_literal (plugin->profile,
-                                                               "packagekit-refresh::transaction");
+               data->ptask = as_profile_start_literal (plugin->profile,
+                                                       "packagekit-refresh::transaction");
        } else if (status == PK_STATUS_ENUM_FINISHED) {
-               g_clear_pointer (&plugin->priv->ptask, as_profile_task_free);
+               g_clear_pointer (&data->ptask, as_profile_task_free);
        }
 
        plugin_status = packagekit_status_enum_to_plugin_status (status);
@@ -107,6 +112,7 @@ gs_plugin_refresh (GsPlugin *plugin,
 {
        PkBitfield filter;
        PkBitfield transaction_flags;
+       ProgressData data;
        g_auto(GStrv) package_ids = NULL;
        g_autoptr(PkPackageSack) sack = NULL;
        g_autoptr(PkResults) results2 = NULL;
@@ -119,6 +125,8 @@ gs_plugin_refresh (GsPlugin *plugin,
        /* cache age of 0 is user-initiated */
        pk_client_set_background (PK_CLIENT (plugin->priv->task), cache_age > 0);
 
+       data.plugin = plugin;
+
        /* update UI as this might take some time */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
 
@@ -128,7 +136,7 @@ gs_plugin_refresh (GsPlugin *plugin,
        results = pk_client_get_updates (PK_CLIENT (plugin->priv->task),
                                         filter,
                                         cancellable,
-                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        gs_plugin_packagekit_progress_cb, &data,
                                         error);
        if (results == NULL)
                return FALSE;
@@ -143,7 +151,7 @@ gs_plugin_refresh (GsPlugin *plugin,
                                              transaction_flags,
                                              package_ids,
                                              cancellable,
-                                             gs_plugin_packagekit_progress_cb, plugin,
+                                             gs_plugin_packagekit_progress_cb, &data,
                                              error);
        return results2 != NULL;
 }
@@ -234,6 +242,7 @@ gs_plugin_packagekit_refresh_guess_app_id (GsPlugin *plugin,
                                           GError **error)
 {
        PkFiles *item;
+       ProgressData data;
        guint i;
        guint j;
        gchar **fns;
@@ -241,12 +250,14 @@ gs_plugin_packagekit_refresh_guess_app_id (GsPlugin *plugin,
        g_autoptr(PkResults) results = NULL;
        g_autoptr(GPtrArray) array = NULL;
 
+       data.plugin = plugin;
+
        /* get file list so we can work out ID */
        files = g_strsplit (filename, "\t", -1);
        results = pk_client_get_files_local (PK_CLIENT (plugin->priv->task),
                                             files,
                                             cancellable,
-                                            gs_plugin_packagekit_progress_cb, plugin,
+                                            gs_plugin_packagekit_progress_cb, &data,
                                             error);
        if (results == NULL)
                return FALSE;
@@ -290,6 +301,7 @@ gs_plugin_filename_to_app (GsPlugin *plugin,
        const gchar *package_id;
        gboolean supported;
        PkDetails *item;
+       ProgressData data;
        g_autoptr (PkResults) results = NULL;
        g_autofree gchar *basename = NULL;
        g_auto(GStrv) files = NULL;
@@ -306,13 +318,15 @@ gs_plugin_filename_to_app (GsPlugin *plugin,
        if (!supported)
                return TRUE;
 
+       data.plugin = plugin;
+
        /* get details */
        files = g_strsplit (filename, "\t", -1);
        pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT);
        results = pk_client_get_details_local (PK_CLIENT (plugin->priv->task),
                                               files,
                                               cancellable,
-                                              gs_plugin_packagekit_progress_cb, plugin,
+                                              gs_plugin_packagekit_progress_cb, &data,
                                               error);
        if (results == NULL)
                return FALSE;


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