[gnome-software/wip/hughsie/GsPluginFailureFlags] f



commit f922625957c7e56bea9889e6b0eeea23b243172b
Author: Richard Hughes <richard hughsie com>
Date:   Wed Nov 23 21:43:11 2016 +0000

    f

 src/gs-plugin-loader.c |  461 ++++++++++++++++++++----------------------------
 src/gs-self-test.c     |    1 +
 2 files changed, 193 insertions(+), 269 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 0d246e1..b3aadd7 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -155,7 +155,9 @@ typedef void                 (*GsPluginAdoptAppFunc)        (GsPlugin       *plugin,
 
 /* async state */
 typedef struct {
+       GsPluginLoader                  *plugin_loader;
        const gchar                     *function_name;
+       const gchar                     *function_name_parent;
        GsAppList                       *list;
        GPtrArray                       *catlist;
        GsPluginRefineFlags              refine_flags;
@@ -171,9 +173,18 @@ typedef struct {
        GsPluginAction                   action;
 } GsPluginLoaderAsyncState;
 
+static GsPluginLoaderAsyncState *
+gs_plugin_loader_async_state_new (GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderAsyncState *state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state->plugin_loader = g_object_ref (plugin_loader);
+       return state;
+}
+
 static void
-gs_plugin_loader_free_async_state (GsPluginLoaderAsyncState *state)
+gs_plugin_loader_async_state_free (GsPluginLoaderAsyncState *state)
 {
+       g_object_unref (state->plugin_loader);
        if (state->category != NULL)
                g_object_unref (state->category);
        if (state->app != NULL)
@@ -193,6 +204,8 @@ gs_plugin_loader_free_async_state (GsPluginLoaderAsyncState *state)
        g_slice_free (GsPluginLoaderAsyncState, state);
 }
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GsPluginLoaderAsyncState, gs_plugin_loader_async_state_free)
+
 static gint
 gs_plugin_loader_app_sort_name_cb (GsApp *app1, GsApp *app2, gpointer user_data)
 {
@@ -343,12 +356,8 @@ gs_plugin_loader_is_error_fatal (GsPluginFailureFlags failure_flags, GError *err
 }
 
 static gboolean
-gs_plugin_error_handle_failure (GsPluginLoader *plugin_loader,
+gs_plugin_error_handle_failure (GsPluginLoaderAsyncState *state,
                                GsPlugin *plugin,
-                               GsApp *app,
-                               GsPluginAction action,
-                               const gchar *function_name,
-                               GsPluginFailureFlags failure_flags,
                                const GError *error_local,
                                GError **error)
 {
@@ -356,30 +365,30 @@ gs_plugin_error_handle_failure (GsPluginLoader *plugin_loader,
        if (error_local == NULL) {
                g_critical ("%s did not set error for %s",
                            gs_plugin_get_name (plugin),
-                           function_name);
+                           state->function_name);
                return TRUE;
        }
 
        /* abort early to allow main thread to process */
-       if (gs_plugin_loader_is_error_fatal (failure_flags, error_local)) {
+       if (gs_plugin_loader_is_error_fatal (state->failure_flags, error_local)) {
                if (error != NULL)
                        *error = g_error_copy (error_local);
                return FALSE;
        }
 
        /* create event which is handled by the GsShell */
-       if (failure_flags & GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS) {
-               gs_plugin_loader_create_event_from_error (plugin_loader,
-                                                         action,
+       if (state->failure_flags & GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS) {
+               gs_plugin_loader_create_event_from_error (state->plugin_loader,
+                                                         state->action,
                                                          plugin,
-                                                         app,
+                                                         state->app,
                                                          error_local);
        }
 
        /* fallback to console warning */
-       if ((failure_flags & GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE) == 0) {
+       if ((state->failure_flags & GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE) == 0) {
                g_warning ("failed to call %s on %s: %s",
-                          function_name,
+                          state->function_name,
                           gs_plugin_get_name (plugin),
                           error_local->message);
        }
@@ -444,105 +453,85 @@ gs_plugin_loader_review_score_sort_cb (gconstpointer a, gconstpointer b)
 }
 
 static void
-gs_plugin_loader_run_refine_wildcard (GsPluginLoader *plugin_loader,
+gs_plugin_loader_run_refine_wildcard (GsPluginLoaderAsyncState *state,
                                      GsPlugin *plugin,
                                      GsApp *app,
-                                     GsAppList *list,
-                                     GsPluginRefineFlags refine_flags,
-                                     GsPluginFailureFlags failure_flags,
                                      GCancellable *cancellable)
 {
        GsPluginRefineWildcardFunc plugin_func = NULL;
-       const gchar *function_name = "gs_plugin_refine_wildcard";
        gboolean ret;
        g_autoptr(GError) error_local = NULL;
 
        /* load the possible symbols */
        g_module_symbol (gs_plugin_get_module (plugin),
-                        function_name,
+                        state->function_name,
                         (gpointer *) &plugin_func);
        if (plugin_func == NULL)
                return;
 
-       gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
-       ret = plugin_func (plugin, app, list, refine_flags,
+       gs_plugin_loader_action_start (state->plugin_loader, plugin, FALSE);
+       ret = plugin_func (plugin, app, state->list, state->refine_flags,
                           cancellable, &error_local);
-       gs_plugin_loader_action_stop (plugin_loader, plugin);
+       gs_plugin_loader_action_stop (state->plugin_loader, plugin);
        if (!ret) {
-               gs_plugin_error_handle_failure (plugin_loader,
+               gs_plugin_error_handle_failure (state,
                                                plugin,
-                                               NULL, /* app */
-                                               GS_PLUGIN_ACTION_REFINE,
-                                               function_name,
-                                               failure_flags,
                                                error_local,
                                                NULL);
        }
 }
 
 static void
-gs_plugin_loader_run_refine_app (GsPluginLoader *plugin_loader,
-                               GsPlugin *plugin,
-                               GsApp *app,
-                               GsAppList *list,
-                               GsPluginRefineFlags refine_flags,
-                               GsPluginFailureFlags failure_flags,
-                               GCancellable *cancellable)
+gs_plugin_loader_run_refine_app (GsPluginLoaderAsyncState *state,
+                                GsPlugin *plugin,
+                                GsApp *app,
+                                GCancellable *cancellable)
 {
        GsPluginRefineAppFunc plugin_func = NULL;
-       const gchar *function_name = "gs_plugin_refine_app";
        gboolean ret;
        g_autoptr(GError) error_local = NULL;
 
        g_module_symbol (gs_plugin_get_module (plugin),
-                        function_name,
+                        state->function_name,
                         (gpointer *) &plugin_func);
        if (plugin_func == NULL)
                return;
 
-       gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
-       ret = plugin_func (plugin, app, refine_flags,
+       gs_plugin_loader_action_start (state->plugin_loader, plugin, FALSE);
+       ret = plugin_func (plugin, app, state->refine_flags,
                           cancellable, &error_local);
-       gs_plugin_loader_action_stop (plugin_loader, plugin);
+       gs_plugin_loader_action_stop (state->plugin_loader, plugin);
        if (!ret) {
-               gs_plugin_error_handle_failure (plugin_loader,
+               gs_plugin_error_handle_failure (state,
                                                plugin,
-                                               app,
-                                               GS_PLUGIN_ACTION_REFINE,
-                                               function_name,
-                                               failure_flags,
                                                error_local,
                                                NULL);
        }
 }
 
 static gboolean
-gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
-                                     const gchar *function_name_parent,
+gs_plugin_loader_run_refine_internal (GsPluginLoaderAsyncState *state,
                                      GsAppList *list,
-                                     GsPluginRefineFlags refine_flags,
-                                     GsPluginFailureFlags failure_flags,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (state->plugin_loader);
        guint i;
        guint j;
        GPtrArray *addons;
        GPtrArray *related;
        GsApp *app;
        GsPlugin *plugin;
-       const gchar *function_name = "gs_plugin_refine";
        gboolean ret = TRUE;
 
        /* this implies the other */
-       if (refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_UI)
-               refine_flags |= GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN;
-       if (refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME)
-               refine_flags |= GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN;
+       if (state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_UI)
+               state->refine_flags |= GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN;
+       if (state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME)
+               state->refine_flags |= GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN;
 
        /* try to adopt each application with a plugin */
-       gs_plugin_loader_run_adopt (plugin_loader, list);
+       gs_plugin_loader_run_adopt (state->plugin_loader, list);
 
        /* run each plugin */
        for (i = 0; i < priv->plugins->len; i++) {
@@ -554,41 +543,37 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
                        continue;
 
                /* load the possible symbols */
+               state->function_name = "gs_plugin_refine";
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
 
                /* profile the plugin runtime */
-               if (function_name_parent == NULL) {
+               if (state->function_name_parent == NULL) {
                        ptask = as_profile_start (priv->profile,
                                                  "GsPlugin::%s(%s)",
                                                  gs_plugin_get_name (plugin),
-                                                 function_name);
+                                                 state->function_name);
                } else {
                        ptask = as_profile_start (priv->profile,
                                                  "GsPlugin::%s(%s;%s)",
                                                  gs_plugin_get_name (plugin),
-                                                 function_name_parent,
-                                                 function_name);
+                                                 state->function_name_parent,
+                                                 state->function_name);
                }
                g_assert (ptask != NULL);
 
                /* run the batched plugin symbol then the per-app plugin */
                if (plugin_func != NULL) {
-                       g_autoptr(GError) error_local = NULL;
                        gboolean ret_local;
-
-                       gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
-                       ret_local = plugin_func (plugin, list, refine_flags,
+                       g_autoptr(GError) error_local = NULL;
+                       gs_plugin_loader_action_start (state->plugin_loader, plugin, FALSE);
+                       ret_local = plugin_func (plugin, list, state->refine_flags,
                                                 cancellable, &error_local);
-                       gs_plugin_loader_action_stop (plugin_loader, plugin);
+                       gs_plugin_loader_action_stop (state->plugin_loader, plugin);
                        if (!ret_local) {
-                               gs_plugin_error_handle_failure (plugin_loader,
+                               gs_plugin_error_handle_failure (state,
                                                                plugin,
-                                                               NULL, /* app */
-                                                               GS_PLUGIN_ACTION_REFINE,
-                                                               function_name,
-                                                               failure_flags,
                                                                error_local,
                                                                NULL);
                                continue;
@@ -597,28 +582,24 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
                for (j = 0; j < gs_app_list_length (list); j++) {
                        app = gs_app_list_index (list, j);
                        if (!gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX)) {
-                               gs_plugin_loader_run_refine_app (plugin_loader,
+                               state->function_name = "gs_plugin_refine_app";
+                               gs_plugin_loader_run_refine_app (state,
                                                                 plugin,
                                                                 app,
-                                                                list,
-                                                                refine_flags,
-                                                                failure_flags,
                                                                 cancellable);
                                continue;
                        }
-                       gs_plugin_loader_run_refine_wildcard (plugin_loader,
+                       state->function_name = "gs_plugin_refine_wildcard";
+                       gs_plugin_loader_run_refine_wildcard (state,
                                                              plugin,
                                                              app,
-                                                             list,
-                                                             refine_flags,
-                                                             failure_flags,
                                                              cancellable);
                }
                gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
        }
 
        /* ensure these are sorted by score */
-       if ((refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS) > 0) {
+       if ((state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS) > 0) {
                GPtrArray *reviews;
                for (i = 0; i < gs_app_list_length (list); i++) {
                        app = gs_app_list_index (list, i);
@@ -629,12 +610,12 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
        }
 
        /* refine addons one layer deep */
-       if ((refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS) > 0) {
+       if ((state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS) > 0) {
                g_autoptr(GsAppList) addons_list = NULL;
 
-               refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS;
-               refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS;
-               refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS;
+               state->refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS;
+               state->refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS;
+               state->refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS;
                addons_list = gs_app_list_new ();
                for (i = 0; i < gs_app_list_length (list); i++) {
                        app = gs_app_list_index (list, i);
@@ -648,11 +629,8 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
                        }
                }
                if (gs_app_list_length (addons_list) > 0) {
-                       ret = gs_plugin_loader_run_refine_internal (plugin_loader,
-                                                                   function_name_parent,
+                       ret = gs_plugin_loader_run_refine_internal (state,
                                                                    addons_list,
-                                                                   refine_flags,
-                                                                   failure_flags,
                                                                    cancellable,
                                                                    error);
                        if (!ret)
@@ -661,7 +639,7 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
        }
 
        /* also do runtime */
-       if ((refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED) > 0) {
+       if ((state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED) > 0) {
                g_autoptr(GsAppList) list2 = gs_app_list_new ();
                for (i = 0; i < gs_app_list_length (list); i++) {
                        GsApp *runtime;
@@ -671,11 +649,8 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
                                gs_app_list_add (list2, runtime);
                }
                if (gs_app_list_length (list2) > 0) {
-                       ret = gs_plugin_loader_run_refine_internal (plugin_loader,
-                                                                   function_name_parent,
+                       ret = gs_plugin_loader_run_refine_internal (state,
                                                                    list2,
-                                                                   refine_flags,
-                                                                   failure_flags,
                                                                    cancellable,
                                                                    error);
                        if (!ret)
@@ -684,10 +659,10 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
        }
 
        /* also do related packages one layer deep */
-       if ((refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED) > 0) {
+       if ((state->refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED) > 0) {
                g_autoptr(GsAppList) related_list = NULL;
 
-               refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED;
+               state->refine_flags &= ~GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED;
                related_list = gs_app_list_new ();
                for (i = 0; i < gs_app_list_length (list); i++) {
                        app = gs_app_list_index (list, i);
@@ -701,11 +676,8 @@ gs_plugin_loader_run_refine_internal (GsPluginLoader *plugin_loader,
                        }
                }
                if (gs_app_list_length (related_list) > 0) {
-                       ret = gs_plugin_loader_run_refine_internal (plugin_loader,
-                                                                   function_name_parent,
+                       ret = gs_plugin_loader_run_refine_internal (state,
                                                                    related_list,
-                                                                   refine_flags,
-                                                                   failure_flags,
                                                                    cancellable,
                                                                    error);
                        if (!ret)
@@ -730,6 +702,7 @@ gs_plugin_loader_run_refine (GsPluginLoader *plugin_loader,
        gboolean ret;
        guint i;
        g_autoptr(GsAppList) freeze_list = NULL;
+       g_autoptr(GsPluginLoaderAsyncState) state = NULL;
 
        /* nothing to do */
        if (gs_app_list_length (list) == 0)
@@ -743,13 +716,13 @@ gs_plugin_loader_run_refine (GsPluginLoader *plugin_loader,
        }
 
        /* first pass */
-       ret = gs_plugin_loader_run_refine_internal (plugin_loader,
-                                                   function_name_parent,
-                                                   list,
-                                                   refine_flags,
-                                                   failure_flags,
-                                                   cancellable,
-                                                   error);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
+       state->function_name_parent = function_name_parent;
+       state->action = GS_PLUGIN_ACTION_REFINE;
+       state->list = g_object_ref (list);
+       state->refine_flags = refine_flags;
+       state->failure_flags = failure_flags;
+       ret = gs_plugin_loader_run_refine_internal (state, list, cancellable, error);
        if (!ret)
                goto out;
 
@@ -763,14 +736,9 @@ gs_plugin_loader_run_refine (GsPluginLoader *plugin_loader,
        }
        if (has_match_any_prefix) {
                g_debug ("2nd resolve pass for unadopted wildcards");
-               ret = gs_plugin_loader_run_refine_internal (plugin_loader,
-                                                           function_name_parent,
-                                                           list,
-                                                           refine_flags,
-                                                           failure_flags,
-                                                           cancellable,
-                                                           error);
-               if (!ret)
+               if (!gs_plugin_loader_run_refine_internal (state, list,
+                                                          cancellable,
+                                                          error))
                        goto out;
        }
 
@@ -793,11 +761,11 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
                              GError **error)
 {
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
-       g_autoptr(GsAppList) list = NULL;
        GsPlugin *plugin;
        gboolean ret = TRUE;
        guint i;
        g_autoptr(AsProfileTask) ptask = NULL;
+       g_autoptr(GsPluginLoaderAsyncState) state = NULL;
 
        g_return_val_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader), NULL);
        g_return_val_if_fail (function_name != NULL, NULL);
@@ -809,7 +777,11 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
        g_assert (ptask != NULL);
 
        /* run each plugin */
-       list = gs_app_list_new ();
+       state = gs_plugin_loader_async_state_new (plugin_loader);
+       state->function_name = function_name;
+       state->action = action;
+       state->failure_flags = failure_flags;
+       state->list = gs_app_list_new ();
        for (i = 0; i < priv->plugins->len; i++) {
                GsPluginResultsFunc plugin_func = NULL;
                g_autoptr(GError) error_local = NULL;
@@ -837,15 +809,11 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
                                           function_name);
                g_assert (ptask2 != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
-               ret = plugin_func (plugin, list, cancellable, &error_local);
+               ret = plugin_func (plugin, state->list, cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       gs_plugin_error_handle_failure (plugin_loader,
+                       gs_plugin_error_handle_failure (state,
                                                        plugin,
-                                                       NULL, /* app */
-                                                       action,
-                                                       function_name,
-                                                       failure_flags,
                                                        error_local,
                                                        NULL);
                        continue;
@@ -856,7 +824,7 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
        /* run refine() on each one */
        ret = gs_plugin_loader_run_refine (plugin_loader,
                                           function_name,
-                                          list,
+                                          state->list,
                                           refine_flags,
                                           failure_flags,
                                           cancellable,
@@ -864,7 +832,7 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
        if (!ret)
                return NULL;
 
-       return g_steal_pointer (&list);
+       return g_steal_pointer (&state->list);
 }
 
 static const gchar *
@@ -1128,8 +1096,14 @@ gs_plugin_loader_run_action (GsPluginLoader *plugin_loader,
        gboolean anything_ran = FALSE;
        gboolean ret;
        guint i;
+       g_autoptr(GsPluginLoaderAsyncState) state = NULL;
 
        /* run each plugin */
+       state = gs_plugin_loader_async_state_new (plugin_loader);
+       state->function_name = function_name;
+       state->action = action;
+       state->app = g_object_ref (app);
+       state->failure_flags = failure_flags;
        for (i = 0; i < priv->plugins->len; i++) {
                GsPluginActionFunc plugin_func = NULL;
                g_autoptr(AsProfileTask) ptask = NULL;
@@ -1143,25 +1117,21 @@ gs_plugin_loader_run_action (GsPluginLoader *plugin_loader,
                        return FALSE;
                }
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                ret = plugin_func (plugin, app, cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       if (!gs_plugin_error_handle_failure (plugin_loader,
+                       if (!gs_plugin_error_handle_failure (state,
                                                             plugin,
-                                                            NULL, /* app */
-                                                            action,
-                                                            function_name,
-                                                            failure_flags,
                                                             error_local,
                                                             error)) {
                                return FALSE;
@@ -1372,14 +1342,14 @@ gs_plugin_loader_get_updates_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_UPDATES;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_updates_thread_cb);
 }
 
@@ -1455,14 +1425,14 @@ gs_plugin_loader_get_distro_upgrades_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_DISTRO_UPDATES;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_distro_upgrades_thread_cb);
 }
 
@@ -1538,14 +1508,14 @@ gs_plugin_loader_get_unvoted_reviews_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_UNVOTED_REVIEWS;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_unvoted_reviews_thread_cb);
 }
 
@@ -1624,14 +1594,14 @@ gs_plugin_loader_get_sources_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_SOURCES;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_sources_thread_cb);
 }
 
@@ -1723,14 +1693,14 @@ gs_plugin_loader_get_installed_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_INSTALLED;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_installed_thread_cb);
 }
 
@@ -1825,14 +1795,14 @@ gs_plugin_loader_get_popular_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_POPULAR;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_popular_thread_cb);
 }
 
@@ -1941,14 +1911,14 @@ gs_plugin_loader_get_featured_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->action = GS_PLUGIN_ACTION_GET_FEATURED;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_featured_thread_cb);
 }
 
@@ -2080,17 +2050,10 @@ gs_plugin_loader_search_thread_cb (GTask *task,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       /* badly behaved plugin */
-                       if (error_local == NULL) {
-                               g_critical ("%s did not set error for %s",
-                                           gs_plugin_get_name (plugin),
-                                           function_name);
-                               continue;
-                       }
-                       g_warning ("failed to call %s on %s: %s",
-                                  function_name,
-                                  gs_plugin_get_name (plugin),
-                                  error_local->message);
+                       gs_plugin_error_handle_failure (state,
+                                                       plugin,
+                                                       error_local,
+                                                       NULL);
                        continue;
                }
                gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
@@ -2171,7 +2134,7 @@ gs_plugin_loader_search_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->list = gs_app_list_new ();
@@ -2180,7 +2143,7 @@ gs_plugin_loader_search_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_search_thread_cb);
 }
 
@@ -2249,17 +2212,10 @@ gs_plugin_loader_search_files_thread_cb (GTask *task,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       /* badly behaved plugin */
-                       if (error_local == NULL) {
-                               g_critical ("%s did not set error for %s",
-                                           gs_plugin_get_name (plugin),
-                                           function_name);
-                               continue;
-                       }
-                       g_warning ("failed to call %s on %s: %s",
-                                  function_name,
-                                  gs_plugin_get_name (plugin),
-                                  error_local->message);
+                       gs_plugin_error_handle_failure (state,
+                                                       plugin,
+                                                       error_local,
+                                                       NULL);
                        continue;
                }
                gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
@@ -2341,7 +2297,7 @@ gs_plugin_loader_search_files_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->list = gs_app_list_new ();
@@ -2350,7 +2306,7 @@ gs_plugin_loader_search_files_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_search_files_thread_cb);
 }
 
@@ -2419,17 +2375,10 @@ gs_plugin_loader_search_what_provides_thread_cb (GTask *task,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       /* badly behaved plugin */
-                       if (error_local == NULL) {
-                               g_critical ("%s did not set error for %s",
-                                           gs_plugin_get_name (plugin),
-                                           function_name);
-                               continue;
-                       }
-                       g_warning ("failed to call %s on %s: %s",
-                                  function_name,
-                                  gs_plugin_get_name (plugin),
-                                  error_local->message);
+                       gs_plugin_error_handle_failure (state,
+                                                       plugin,
+                                                       error_local,
+                                                       NULL);
                        continue;
                }
                gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
@@ -2511,7 +2460,7 @@ gs_plugin_loader_search_what_provides_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->list = gs_app_list_new ();
@@ -2520,7 +2469,7 @@ gs_plugin_loader_search_what_provides_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_search_what_provides_thread_cb);
 }
 
@@ -2607,6 +2556,7 @@ gs_plugin_loader_get_categories_thread_cb (GTask *task,
        guint i;
 
        /* run each plugin */
+       state->function_name = function_name;
        for (i = 0; i < priv->plugins->len; i++) {
                g_autoptr(AsProfileTask) ptask = NULL;
                g_autoptr(GError) error_local = NULL;
@@ -2616,26 +2566,22 @@ gs_plugin_loader_get_categories_thread_cb (GTask *task,
                if (g_task_return_error_if_cancelled (task))
                        return;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                ret = plugin_func (plugin, state->catlist,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       gs_plugin_error_handle_failure (plugin_loader,
+                       gs_plugin_error_handle_failure (state,
                                                        plugin,
-                                                       NULL, /* app */
-                                                       state->action,
-                                                       function_name,
-                                                       state->failure_flags,
                                                        error_local,
                                                        NULL);
                        continue;
@@ -2690,7 +2636,7 @@ gs_plugin_loader_get_categories_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->catlist = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
@@ -2698,7 +2644,7 @@ gs_plugin_loader_get_categories_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_categories_thread_cb);
 }
 
@@ -2740,6 +2686,7 @@ gs_plugin_loader_get_category_apps_thread_cb (GTask *task,
        guint i;
 
        /* run each plugin */
+       state->function_name = function_name;
        for (i = 0; i < priv->plugins->len; i++) {
                g_autoptr(AsProfileTask) ptask = NULL;
                g_autoptr(GError) error_local = NULL;
@@ -2749,26 +2696,22 @@ gs_plugin_loader_get_category_apps_thread_cb (GTask *task,
                if (g_task_return_error_if_cancelled (task))
                        return;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                ret = plugin_func (plugin, state->category, state->list,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       if (!gs_plugin_error_handle_failure (plugin_loader,
+                       if (!gs_plugin_error_handle_failure (state,
                                                             plugin,
-                                                            NULL, /* app */
-                                                            state->action,
-                                                            function_name,
-                                                            state->failure_flags,
                                                             error_local,
                                                             NULL)) {
                                g_task_return_error (task, error_local);
@@ -2847,7 +2790,7 @@ gs_plugin_loader_get_category_apps_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->list = gs_app_list_new ();
@@ -2856,7 +2799,7 @@ gs_plugin_loader_get_category_apps_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_get_category_apps_thread_cb);
 }
 
@@ -2888,7 +2831,7 @@ gs_plugin_loader_app_refine_thread_cb (GTask *task,
                                       GCancellable *cancellable)
 {
        GError *error = NULL;
-       GsAppList *list;
+       g_autoptr(GsAppList) list = NULL;
        GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) task_data;
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
        gboolean ret;
@@ -2904,13 +2847,11 @@ gs_plugin_loader_app_refine_thread_cb (GTask *task,
                                           &error);
        if (!ret) {
                g_task_return_error (task, error);
-               goto out;
+               return;
        }
 
        /* success */
        g_task_return_boolean (task, TRUE);
-out:
-       g_object_unref (list);
 }
 
 /**
@@ -2936,7 +2877,7 @@ gs_plugin_loader_app_refine_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->app = g_object_ref (app);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
@@ -2948,7 +2889,7 @@ gs_plugin_loader_app_refine_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_app_refine_thread_cb);
 }
 
@@ -3103,12 +3044,8 @@ gs_plugin_loader_review_action_thread_cb (GTask *task,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       if (!gs_plugin_error_handle_failure (plugin_loader,
+                       if (!gs_plugin_error_handle_failure (state,
                                                             plugin,
-                                                            state->app,
-                                                            state->action,
-                                                            state->function_name,
-                                                            state->failure_flags,
                                                             error_local,
                                                             NULL)) {
                                g_task_return_error (task, error_local);
@@ -3346,7 +3283,7 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
        }
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->app = g_object_ref (app);
        state->action = action;
 
@@ -3385,7 +3322,7 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_app_action_thread_cb);
 }
 
@@ -3407,7 +3344,7 @@ gs_plugin_loader_review_action_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->app = g_object_ref (app);
        state->review = g_object_ref (review);
        state->action = action;
@@ -3439,7 +3376,7 @@ gs_plugin_loader_review_action_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_review_action_thread_cb);
 }
 
@@ -3500,12 +3437,8 @@ gs_plugin_loader_auth_action_thread_cb (GTask *task,
                ret = plugin_func (plugin, state->auth, cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       if (!gs_plugin_error_handle_failure (plugin_loader,
+                       if (!gs_plugin_error_handle_failure (state,
                                                             plugin,
-                                                            NULL, /* app */
-                                                            state->action,
-                                                            state->function_name,
-                                                            state->failure_flags,
                                                             error_local,
                                                             NULL)) {
                                g_task_return_error (task, error_local);
@@ -3537,7 +3470,7 @@ gs_plugin_loader_auth_action_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->auth = g_object_ref (auth);
        state->action = action;
        state->failure_flags = failure_flags;
@@ -3562,7 +3495,7 @@ gs_plugin_loader_auth_action_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_auth_action_thread_cb);
 }
 
@@ -4020,6 +3953,7 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
        guint j;
        g_autoptr(GDir) dir = NULL;
        g_autoptr(AsProfileTask) ptask = NULL;
+       g_autoptr(GsPluginLoaderAsyncState) state = NULL;
 
        g_return_val_if_fail (priv->location != NULL, FALSE);
 
@@ -4216,9 +4150,12 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
        } while (changes);
 
        /* run setup */
+       state = gs_plugin_loader_async_state_new (plugin_loader);
+       state->function_name = "gs_plugin_setup";
+       state->action = GS_PLUGIN_ACTION_SETUP;
+       state->failure_flags = failure_flags | GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE;
        for (i = 0; i < priv->plugins->len; i++) {
                GsPluginSetupFunc plugin_func = NULL;
-               const gchar *function_name = "gs_plugin_setup";
                gboolean ret;
                g_autoptr(AsProfileTask) ptask2 = NULL;
                g_autoptr(GError) error_local = NULL;
@@ -4228,25 +4165,21 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
                if (!gs_plugin_get_enabled (plugin))
                        continue;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask2 = as_profile_start (priv->profile,
                                           "GsPlugin::%s(%s)",
                                           gs_plugin_get_name (plugin),
-                                          function_name);
+                                          state->function_name);
                g_assert (ptask2 != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, TRUE);
                ret = plugin_func (plugin, NULL, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       gs_plugin_error_handle_failure (plugin_loader,
+                       gs_plugin_error_handle_failure (state,
                                                        plugin,
-                                                       NULL, /* app */
-                                                       GS_PLUGIN_ACTION_SETUP,
-                                                       function_name,
-                                                       failure_flags | GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE,
                                                        error_local,
                                                        NULL);
                        g_debug ("disabling %s as setup failed: %s",
@@ -4578,12 +4511,16 @@ gs_plugin_loader_run_refresh (GsPluginLoader *plugin_loader,
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
        GsPlugin *plugin;
        GsPluginRefreshFunc plugin_func = NULL;
-       const gchar *function_name = "gs_plugin_refresh";
        gboolean anything_ran = FALSE;
        gboolean ret;
        guint i;
+       g_autoptr(GsPluginLoaderAsyncState) state = NULL;
 
        /* run each plugin */
+       state = gs_plugin_loader_async_state_new (plugin_loader);
+       state->function_name = "gs_plugin_refresh";
+       state->action = GS_PLUGIN_ACTION_REFRESH;
+       state->failure_flags = failure_flags;
        for (i = 0; i < priv->plugins->len; i++) {
                g_autoptr(GError) error_local = NULL;
                g_autoptr(AsProfileTask) ptask = NULL;
@@ -4597,25 +4534,21 @@ gs_plugin_loader_run_refresh (GsPluginLoader *plugin_loader,
                }
 
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, TRUE);
                ret = plugin_func (plugin, cache_age, refresh_flags, cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       if (!gs_plugin_error_handle_failure (plugin_loader,
+                       if (!gs_plugin_error_handle_failure (state,
                                                             plugin,
-                                                            NULL, /* app */
-                                                            GS_PLUGIN_ACTION_REFRESH,
-                                                            function_name,
-                                                            failure_flags,
                                                             error_local,
                                                             error)) {
                                return FALSE;
@@ -4686,7 +4619,7 @@ gs_plugin_loader_refresh_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refresh_flags = refresh_flags;
        state->failure_flags = failure_flags;
        state->cache_age = cache_age;
@@ -4694,7 +4627,7 @@ gs_plugin_loader_refresh_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_refresh_thread_cb);
 }
 
@@ -4749,6 +4682,7 @@ gs_plugin_loader_file_to_app_thread_cb (GTask *task,
        GsPluginFileToAppFunc plugin_func = NULL;
 
        /* run each plugin */
+       state->function_name = function_name;
        for (i = 0; i < priv->plugins->len; i++) {
                g_autoptr(AsProfileTask) ptask = NULL;
                g_autoptr(GError) error_local = NULL;
@@ -4758,26 +4692,22 @@ gs_plugin_loader_file_to_app_thread_cb (GTask *task,
                if (g_task_return_error_if_cancelled (task))
                        return;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                ret = plugin_func (plugin, state->list, state->file,
                                   cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       gs_plugin_error_handle_failure (plugin_loader,
+                       gs_plugin_error_handle_failure (state,
                                                        plugin,
-                                                       NULL, /* app */
-                                                       state->action,
-                                                       function_name,
-                                                       state->failure_flags,
                                                        error_local,
                                                        NULL);
                        continue;
@@ -4881,7 +4811,7 @@ gs_plugin_loader_file_to_app_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->refine_flags = refine_flags;
        state->failure_flags = failure_flags;
        state->list = gs_app_list_new ();
@@ -4890,7 +4820,7 @@ gs_plugin_loader_file_to_app_async (GsPluginLoader *plugin_loader,
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_file_to_app_thread_cb);
 }
 
@@ -4923,13 +4853,13 @@ gs_plugin_loader_update_thread_cb (GTask *task,
 {
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
-       const gchar *function_name = "gs_plugin_update";
        gboolean ret = TRUE;
        GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) task_data;
        GsPlugin *plugin;
        guint i;
 
        /* run each plugin */
+       state->function_name = "gs_plugin_update";
        for (i = 0; i < priv->plugins->len; i++) {
                GsPluginUpdateFunc plugin_func = NULL;
                g_autoptr(AsProfileTask) ptask = NULL;
@@ -4940,25 +4870,21 @@ gs_plugin_loader_update_thread_cb (GTask *task,
                if (g_task_return_error_if_cancelled (task))
                        return;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_func);
                if (plugin_func == NULL)
                        continue;
                ptask = as_profile_start (priv->profile,
                                          "GsPlugin::%s(%s)",
                                          gs_plugin_get_name (plugin),
-                                         function_name);
+                                         state->function_name);
                g_assert (ptask != NULL);
                gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                ret = plugin_func (plugin, state->list, cancellable, &error_local);
                gs_plugin_loader_action_stop (plugin_loader, plugin);
                if (!ret) {
-                       gs_plugin_error_handle_failure (plugin_loader,
+                       gs_plugin_error_handle_failure (state,
                                                        plugin,
-                                                       NULL, /* app */
-                                                       state->action,
-                                                       function_name,
-                                                       state->failure_flags,
                                                        error_local,
                                                        NULL);
                        continue;
@@ -4967,7 +4893,7 @@ gs_plugin_loader_update_thread_cb (GTask *task,
        }
 
        /* run each plugin, per-app version */
-       function_name = "gs_plugin_update_app";
+       state->function_name = "gs_plugin_update_app";
        for (i = 0; i < priv->plugins->len; i++) {
                GsPluginActionFunc plugin_app_func = NULL;
                guint j;
@@ -4978,7 +4904,7 @@ gs_plugin_loader_update_thread_cb (GTask *task,
                if (g_task_return_error_if_cancelled (task))
                        return;
                g_module_symbol (gs_plugin_get_module (plugin),
-                                function_name,
+                                state->function_name,
                                 (gpointer *) &plugin_app_func);
                if (plugin_app_func == NULL)
                        continue;
@@ -4989,10 +4915,11 @@ gs_plugin_loader_update_thread_cb (GTask *task,
                        g_autoptr(AsProfileTask) ptask = NULL;
                        g_autoptr(GError) error_local = NULL;
 
+                       g_set_object (&state->app, app);
                        ptask = as_profile_start (priv->profile,
                                                  "GsPlugin::%s(%s){%s}",
                                                  gs_plugin_get_name (plugin),
-                                                 function_name,
+                                                 state->function_name,
                                                  gs_app_get_id (app));
                        g_assert (ptask != NULL);
                        gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
@@ -5001,12 +4928,8 @@ gs_plugin_loader_update_thread_cb (GTask *task,
                                               &error_local);
                        gs_plugin_loader_action_stop (plugin_loader, plugin);
                        if (!ret) {
-                               gs_plugin_error_handle_failure (plugin_loader,
+                               gs_plugin_error_handle_failure (state,
                                                                plugin,
-                                                               app,
-                                                               state->action,
-                                                               function_name,
-                                                               state->failure_flags,
                                                                error_local,
                                                                NULL);
                                continue;
@@ -5039,14 +4962,14 @@ gs_plugin_loader_update_async (GsPluginLoader *plugin_loader,
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
        /* save state */
-       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state = gs_plugin_loader_async_state_new (plugin_loader);
        state->list = gs_app_list_copy (apps);
        state->action = GS_PLUGIN_ACTION_UPDATE;
        state->failure_flags = failure_flags;
 
        /* run in a thread */
        task = g_task_new (plugin_loader, cancellable, callback, user_data);
-       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_async_state_free);
        g_task_run_in_thread (task, gs_plugin_loader_update_thread_cb);
 }
 
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 82b2f4c..b2a6e42 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -445,6 +445,7 @@ gs_plugin_loader_error_func (GsPluginLoader *plugin_loader)
        event = gs_plugin_loader_get_event_by_id (plugin_loader,
                                                  "*/*/*/source/dummy/*");
        g_assert (event != NULL);
+       g_assert (gs_plugin_event_get_app (event) != NULL);
        g_assert (gs_plugin_event_get_app (event) == app);
 
        /* get last active event */


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