[gnome-software] Make gs_plugin_loader_app_refine() async



commit 45c44a40ecc25f04f531d50d2331072fe74745f5
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 9 15:04:35 2013 +0100

    Make gs_plugin_loader_app_refine() async
    
    Also provide a sync helper for the self test program to use.

 src/gs-plugin-loader-sync.c |   51 ++++++++++++++
 src/gs-plugin-loader-sync.h |    5 ++
 src/gs-plugin-loader.c      |  157 +++++++++++++++++++++++++++++++++++--------
 src/gs-plugin-loader.h      |    6 ++-
 4 files changed, 189 insertions(+), 30 deletions(-)
---
diff --git a/src/gs-plugin-loader-sync.c b/src/gs-plugin-loader-sync.c
index b4a2688..9ed84ea 100644
--- a/src/gs-plugin-loader-sync.c
+++ b/src/gs-plugin-loader-sync.c
@@ -29,6 +29,7 @@ typedef struct {
        GList           *list;
        GMainContext    *context;
        GMainLoop       *loop;
+       gboolean         ret;
 } GsPluginLoaderHelper;
 
 static void
@@ -258,4 +259,54 @@ gs_plugin_loader_get_category_apps (GsPluginLoader *plugin_loader,
        return helper.list;
 }
 
+/**
+ * gs_plugin_loader_app_refine_finish_sync:
+ **/
+static void
+gs_plugin_loader_app_refine_finish_sync (GsPluginLoader *plugin_loader,
+                                        GAsyncResult *res,
+                                        GsPluginLoaderHelper *helper)
+{
+       helper->ret = gs_plugin_loader_app_refine_finish (plugin_loader,
+                                                         res,
+                                                         helper->error);
+       g_main_loop_quit (helper->loop);
+}
+
+/**
+ * gs_plugin_loader_app_refine:
+ **/
+gboolean
+gs_plugin_loader_app_refine (GsPluginLoader *plugin_loader,
+                            GsApp *app,
+                            GsPluginRefineFlags flags,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+       GsPluginLoaderHelper helper;
+
+       /* create temp object */
+       helper.context = g_main_context_new ();
+       helper.loop = g_main_loop_new (helper.context, FALSE);
+       helper.error = error;
+
+       g_main_context_push_thread_default (helper.context);
+
+       /* run async method */
+       gs_plugin_loader_app_refine_async (plugin_loader,
+                                          app,
+                                          flags,
+                                          cancellable,
+                                          (GAsyncReadyCallback) gs_plugin_loader_app_refine_finish_sync,
+                                          &helper);
+       g_main_loop_run (helper.loop);
+
+       g_main_context_pop_thread_default (helper.context);
+
+       g_main_loop_unref (helper.loop);
+       g_main_context_unref (helper.context);
+
+       return helper.ret;
+}
+
 /* vim: set noexpandtab: */
diff --git a/src/gs-plugin-loader-sync.h b/src/gs-plugin-loader-sync.h
index 8383aa2..d88d113 100644
--- a/src/gs-plugin-loader-sync.h
+++ b/src/gs-plugin-loader-sync.h
@@ -49,6 +49,11 @@ GList                *gs_plugin_loader_get_category_apps     (GsPluginLoader 
*plugin_loader,
                                                         GsPluginRefineFlags flags,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+gboolean        gs_plugin_loader_app_refine            (GsPluginLoader *plugin_loader,
+                                                        GsApp          *app,
+                                                        GsPluginRefineFlags flags,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 
 G_END_DECLS
 
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 77341d7..d0ac7b7 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -418,6 +418,7 @@ typedef struct {
        GsPluginRefineFlags              flags;
        gchar                           *value;
        GsCategory                      *category;
+       GsApp                           *app;
 } GsPluginLoaderAsyncState;
 
 /******************************************************************************/
@@ -1499,6 +1500,133 @@ gs_plugin_loader_get_category_apps_finish (GsPluginLoader *plugin_loader,
 /******************************************************************************/
 
 /**
+ * gs_plugin_loader_app_refine_state_finish:
+ **/
+static void
+gs_plugin_loader_app_refine_state_finish (GsPluginLoaderAsyncState *state,
+                                      const GError *error)
+{
+       if (state->ret) {
+               g_simple_async_result_set_op_res_gboolean (state->res, TRUE);
+       } else {
+               g_simple_async_result_set_from_error (state->res, error);
+       }
+
+       /* deallocate */
+       if (state->cancellable != NULL)
+               g_object_unref (state->cancellable);
+
+       g_free (state->value);
+       gs_plugin_list_free (state->list);
+       g_object_unref (state->app);
+       g_object_unref (state->res);
+       g_object_unref (state->plugin_loader);
+       g_slice_free (GsPluginLoaderAsyncState, state);
+}
+
+/**
+ * gs_plugin_loader_app_refine_thread_cb:
+ **/
+static void
+gs_plugin_loader_app_refine_thread_cb (GSimpleAsyncResult *res,
+                                      GObject *object,
+                                      GCancellable *cancellable)
+{
+       GError *error = NULL;
+       GList *list = NULL;
+       GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) g_object_get_data (G_OBJECT 
(cancellable), "state");
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
+
+       gs_plugin_add_app (&list, state->app);
+       state->ret = gs_plugin_loader_run_refine (plugin_loader,
+                                                 NULL,
+                                                 list,
+                                                 state->flags,
+                                                 cancellable,
+                                                 &error);
+       if (!state->ret) {
+               gs_plugin_loader_app_refine_state_finish (state, error);
+               g_error_free (error);
+               goto out;
+       }
+
+       /* success */
+       gs_plugin_loader_app_refine_state_finish (state, NULL);
+out:
+       gs_plugin_list_free (list);
+}
+
+/**
+ * gs_plugin_loader_app_refine_async:
+ *
+ * This method calls all plugins that implement the gs_plugin_refine()
+ * function.
+ **/
+void
+gs_plugin_loader_app_refine_async (GsPluginLoader *plugin_loader,
+                                  GsApp *app,
+                                  GsPluginRefineFlags flags,
+                                  GCancellable *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer user_data)
+{
+       GCancellable *tmp;
+       GsPluginLoaderAsyncState *state;
+
+       g_return_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader));
+       g_return_if_fail (GS_IS_APP (app));
+       g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+       /* save state */
+       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state->res = g_simple_async_result_new (G_OBJECT (plugin_loader),
+                                               callback,
+                                               user_data,
+                                               gs_plugin_loader_app_refine_async);
+       state->plugin_loader = g_object_ref (plugin_loader);
+       state->app = g_object_ref (app);
+       state->flags = flags;
+       if (cancellable != NULL)
+               state->cancellable = g_object_ref (cancellable);
+
+       /* run in a thread */
+       tmp = g_cancellable_new ();
+       g_object_set_data (G_OBJECT (tmp), "state", state);
+       g_simple_async_result_run_in_thread (G_SIMPLE_ASYNC_RESULT (state->res),
+                                            gs_plugin_loader_app_refine_thread_cb,
+                                            0,
+                                            (GCancellable *) tmp);
+       g_object_unref (tmp);
+}
+
+/**
+ * gs_plugin_loader_app_refine_finish:
+ *
+ * Return value: success
+ **/
+gboolean
+gs_plugin_loader_app_refine_finish (GsPluginLoader *plugin_loader,
+                                   GAsyncResult *res,
+                                   GError **error)
+{
+       GSimpleAsyncResult *simple;
+
+       g_return_val_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader), FALSE);
+       g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+       g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+       /* failed */
+       simple = G_SIMPLE_ASYNC_RESULT (res);
+       if (g_simple_async_result_propagate_error (simple, error))
+               return FALSE;
+
+       /* grab detail */
+       return g_simple_async_result_get_op_res_gboolean (simple);
+}
+
+/******************************************************************************/
+
+/**
  * gs_plugin_loader_run_action:
  **/
 static gboolean
@@ -1779,35 +1907,6 @@ gs_plugin_loader_app_set_rating (GsPluginLoader *plugin_loader,
 }
 
 /**
- * gs_plugin_loader_app_refine:
- *
- * ...really just for make check use.
- **/
-gboolean
-gs_plugin_loader_app_refine (GsPluginLoader *plugin_loader,
-                            GsApp *app,
-                            GsPluginRefineFlags flags,
-                            GCancellable *cancellable,
-                            GError **error)
-{
-       gboolean ret;
-       GList *list = NULL;
-
-       gs_plugin_add_app (&list, app);
-       ret = gs_plugin_loader_run_refine (plugin_loader,
-                                          NULL,
-                                          list,
-                                          flags,
-                                          cancellable,
-                                          error);
-       if (!ret)
-               goto out;
-       gs_plugin_list_free (list);
-out:
-       return ret;
-}
-
-/**
  * gs_plugin_loader_run:
  **/
 static void
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index a9b7e1d..fa72f61 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -135,10 +135,14 @@ gboolean   gs_plugin_loader_set_enabled           (GsPluginLoader *plugin_loader,
                                                         gboolean        enabled);
 void            gs_plugin_loader_set_location          (GsPluginLoader *plugin_loader,
                                                         const gchar    *location);
-gboolean        gs_plugin_loader_app_refine            (GsPluginLoader *plugin_loader,
+void            gs_plugin_loader_app_refine_async      (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,
                                                         GsPluginRefineFlags flags,
                                                         GCancellable   *cancellable,
+                                                        GAsyncReadyCallback callback,
+                                                        gpointer        user_data);
+gboolean        gs_plugin_loader_app_refine_finish     (GsPluginLoader *plugin_loader,
+                                                        GAsyncResult   *res,
                                                         GError         **error);
 void            gs_plugin_loader_app_install           (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,


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