[gnome-software: 35/72] packagekit: Make resolve_packages_with_filter() function async
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 35/72] packagekit: Make resolve_packages_with_filter() function async
- Date: Wed, 15 Dec 2021 13:00:55 +0000 (UTC)
commit df169aa3e959328a0a0b6eb0ee3775a8682bc3a6
Author: Philip Withnall <pwithnall endlessos org>
Date: Mon Oct 25 23:39:26 2021 +0100
packagekit: Make resolve_packages_with_filter() function async
This is another step towards making the whole `gs_plugin_refine()` vfunc
asynchronous.
The async helper in this commit won’t work. It’s illustrative and will
be replaced in a subsequent commit. Similarly, the progress callback
data for `gs_packagekit_helper_cb()` will be reworked subsequently.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
Helps: #1472
plugins/packagekit/gs-plugin-packagekit.c | 139 +++++++++++++++++++++---------
1 file changed, 100 insertions(+), 39 deletions(-)
---
diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c
index 6e32d474c..9f2f3cb6d 100644
--- a/plugins/packagekit/gs-plugin-packagekit.c
+++ b/plugins/packagekit/gs-plugin-packagekit.c
@@ -887,12 +887,17 @@ gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
}
}
-static gboolean
-gs_plugin_packagekit_resolve_packages_with_filter (GsPluginPackagekit *self,
- GsAppList *list,
- PkBitfield filter,
- GCancellable *cancellable,
- GError **error)
+static void resolve_packages_with_filter_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+
+static void
+gs_plugin_packagekit_resolve_packages_with_filter_async (GsPluginPackagekit *self,
+ GsAppList *list,
+ PkBitfield filter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GsPlugin *plugin = GS_PLUGIN (self);
GPtrArray *sources;
@@ -901,9 +906,12 @@ gs_plugin_packagekit_resolve_packages_with_filter (GsPluginPackagekit *self,
guint i;
guint j;
g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);
- g_autoptr(PkResults) results = NULL;
g_autoptr(GPtrArray) package_ids = NULL;
- g_autoptr(GPtrArray) packages = NULL;
+ g_autoptr(GTask) task = NULL;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gs_plugin_packagekit_resolve_packages_with_filter_async);
+ g_task_set_task_data (task, g_object_ref (list), (GDestroyNotify) g_object_unref);
package_ids = g_ptr_array_new_with_free_func (g_free);
for (i = 0; i < gs_app_list_length (list); i++) {
@@ -920,23 +928,48 @@ gs_plugin_packagekit_resolve_packages_with_filter (GsPluginPackagekit *self,
g_ptr_array_add (package_ids, g_strdup (pkgname));
}
}
- if (package_ids->len == 0)
- return TRUE;
+
+ if (package_ids->len == 0) {
+ g_task_return_boolean (task, TRUE);
+ return;
+ }
+
g_ptr_array_add (package_ids, NULL);
/* resolve them all at once */
g_mutex_lock (&self->client_mutex_refine);
pk_client_set_interactive (self->client_refine, gs_plugin_has_flags (plugin,
GS_PLUGIN_FLAGS_INTERACTIVE));
- results = pk_client_resolve (self->client_refine,
- filter,
- (gchar **) package_ids->pdata,
- cancellable,
- gs_packagekit_helper_cb, helper,
- error);
+ pk_client_resolve_async (self->client_refine,
+ filter,
+ (gchar **) package_ids->pdata,
+ cancellable,
+ /* TODO: @helper is leaked here; this will be reworked in a subsequent
commit */
+ gs_packagekit_helper_cb, g_object_ref (helper),
+ resolve_packages_with_filter_cb,
+ g_steal_pointer (&task));
g_mutex_unlock (&self->client_mutex_refine);
- if (!gs_plugin_packagekit_results_valid (results, error)) {
- g_prefix_error (error, "failed to resolve package_ids: ");
- return FALSE;
+}
+
+static void
+resolve_packages_with_filter_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ PkClient *client = PK_CLIENT (source_object);
+ g_autoptr(GTask) task = g_steal_pointer (&user_data);
+ GsPluginPackagekit *self = g_task_get_source_object (task);
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ GsAppList *list = g_task_get_task_data (task);
+ g_autoptr(PkResults) results = NULL;
+ g_autoptr(GPtrArray) packages = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ results = pk_client_generic_finish (client, result, &local_error);
+
+ if (!gs_plugin_packagekit_results_valid (results, &local_error)) {
+ g_prefix_error (&local_error, "failed to resolve package_ids: ");
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ return;
}
/* get results */
@@ -944,18 +977,28 @@ gs_plugin_packagekit_resolve_packages_with_filter (GsPluginPackagekit *self,
/* if the user types more characters we'll get cancelled - don't go on
* to mark apps as unavailable because packages->len = 0 */
- if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
- gs_utils_error_convert_gio (error);
- return FALSE;
+ if (g_cancellable_set_error_if_cancelled (cancellable, &local_error)) {
+ gs_utils_error_convert_gio (&local_error);
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ return;
}
- for (i = 0; i < gs_app_list_length (list); i++) {
- app = gs_app_list_index (list, i);
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
if (gs_app_get_local_file (app) != NULL)
continue;
- gs_plugin_packagekit_resolve_packages_app (plugin, packages, app);
+ gs_plugin_packagekit_resolve_packages_app (GS_PLUGIN (self), packages, app);
}
- return TRUE;
+
+ g_task_return_boolean (task, TRUE);
+}
+
+static gboolean
+gs_plugin_packagekit_resolve_packages_with_filter_finish (GsPluginPackagekit *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/*
@@ -1160,18 +1203,28 @@ gs_plugin_refine (GsPlugin *plugin,
if (gs_app_list_length (resolve_all) > 0) {
PkBitfield filter;
g_autoptr(GsAppList) resolve2_list = NULL;
+ g_autoptr(GAsyncResult) async_result = NULL;
+ g_autoptr(GAsyncResult) async_result2 = NULL;
/* first, try to resolve packages with ARCH filter */
filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST,
PK_FILTER_ENUM_ARCH,
-1);
- if (!gs_plugin_packagekit_resolve_packages_with_filter (self,
- resolve_all,
- filter,
- cancellable,
- error)) {
+
+ /* FIXME: This async-to-sync conversion is very hacky, but is
+ * temporary and will be removed in a subsequent commit. */
+ gs_plugin_packagekit_resolve_packages_with_filter_async (self,
+ resolve_all,
+ filter,
+ cancellable,
+ async_result_cb,
+ &async_result);
+ while (async_result == NULL)
+ g_main_context_iteration (NULL, TRUE);
+ if (!gs_plugin_packagekit_resolve_packages_with_filter_finish (self,
+ async_result,
+ error))
return FALSE;
- }
/* if any packages remaining in UNKNOWN state, try to resolve them again,
* but this time without ARCH filter */
@@ -1185,13 +1238,21 @@ gs_plugin_refine (GsPlugin *plugin,
PK_FILTER_ENUM_NOT_ARCH,
PK_FILTER_ENUM_NOT_SOURCE,
-1);
- if (!gs_plugin_packagekit_resolve_packages_with_filter (self,
- resolve2_list,
- filter,
- cancellable,
- error)) {
+ g_clear_object (&async_result);
+
+ /* FIXME: This async-to-sync conversion is also hacky but temporary. */
+ gs_plugin_packagekit_resolve_packages_with_filter_async (self,
+ resolve2_list,
+ filter,
+ cancellable,
+ async_result_cb,
+ &async_result);
+ while (async_result == NULL)
+ g_main_context_iteration (NULL, TRUE);
+ if (!gs_plugin_packagekit_resolve_packages_with_filter_finish (self,
+ async_result,
+ error))
return FALSE;
- }
}
/* set the package-id for an installed desktop file */
@@ -2304,7 +2365,7 @@ gs_plugin_url_to_app (GsPlugin *plugin,
details_collection = gs_plugin_packagekit_details_array_to_hash (details);
- gs_plugin_packagekit_resolve_packages_app (plugin, packages, app);
+ gs_plugin_packagekit_resolve_packages_app (GS_PLUGIN (self), packages, app);
gs_plugin_packagekit_refine_details_app (plugin, details_collection, app);
gs_app_list_add (list, app);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]