[gnome-software/wip/rancell/bgo789680] Use the correct GCancellable when switching between apps
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/rancell/bgo789680] Use the correct GCancellable when switching between apps
- Date: Tue, 31 Oct 2017 04:00:51 +0000 (UTC)
commit a13319bba9dfd300bbf1f0dda260852ad9ba112f
Author: Robert Ancell <robert ancell canonical com>
Date: Tue Oct 31 16:56:49 2017 +1300
Use the correct GCancellable when switching between apps
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=789680
lib/gs-plugin-loader.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---
lib/gs-plugin-loader.h | 2 +
src/gs-details-page.c | 7 ++++
3 files changed, 78 insertions(+), 5 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 8e0e7a0..62ad0f0 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -50,6 +50,7 @@ typedef struct
GPtrArray *auth_array;
GPtrArray *file_monitors;
GsPluginStatus global_status_last;
+ GPtrArray *tasks;
GMutex pending_apps_mutex;
GPtrArray *pending_apps;
@@ -1602,6 +1603,52 @@ gs_plugin_loader_job_get_categories_thread_cb (GTask *task,
g_task_return_pointer (task, g_ptr_array_ref (helper->catlist), (GDestroyNotify) g_ptr_array_unref);
}
+typedef struct
+{
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} GsTaskHelper;
+
+static GsTaskHelper *
+gs_task_helper_new (GAsyncReadyCallback callback, gpointer user_data)
+{
+ GsTaskHelper *helper = g_slice_new0 (GsTaskHelper);
+ helper->callback = callback;
+ helper->user_data = user_data;
+ return helper;
+}
+
+static void
+gs_task_helper_free (GsTaskHelper *helper)
+{
+ g_slice_free (GsTaskHelper, helper);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GsTaskHelper, gs_task_helper_free)
+
+static void
+task_ready_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (GS_PLUGIN_LOADER (object));
+ g_autoptr(GsTaskHelper) helper = user_data;
+ helper->callback (object, res, helper->user_data);
+ g_ptr_array_remove (priv->tasks, res);
+}
+
+static GTask *
+create_task (GsPluginLoader *plugin_loader, GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
+{
+ GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+ GsTaskHelper *helper;
+ GTask *task;
+
+ helper = gs_task_helper_new (callback, user_data);
+ task = g_task_new (plugin_loader, cancellable, task_ready_cb, helper);
+ g_ptr_array_add (priv->tasks, task);
+
+ return task;
+}
+
/**
* gs_plugin_loader_job_get_categories_async:
*
@@ -1627,7 +1674,7 @@ gs_plugin_loader_job_get_categories_async (GsPluginLoader *plugin_loader,
helper->catlist = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
/* run in a thread */
- task = g_task_new (plugin_loader, cancellable, callback, user_data);
+ task = create_task (plugin_loader, cancellable, callback, user_data);
g_task_set_task_data (task, helper, (GDestroyNotify) gs_plugin_loader_helper_free);
g_task_run_in_thread (task, gs_plugin_loader_job_get_categories_thread_cb);
}
@@ -2702,6 +2749,7 @@ gs_plugin_loader_finalize (GObject *object)
g_free (priv->language);
g_object_unref (priv->global_cache);
g_ptr_array_unref (priv->file_monitors);
+ g_ptr_array_unref (priv->tasks);
g_hash_table_unref (priv->events_by_id);
g_hash_table_unref (priv->disallow_updates);
@@ -2800,6 +2848,7 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
priv->pending_apps = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
priv->auth_array = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
priv->file_monitors = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
+ priv->tasks = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
priv->locations = g_ptr_array_new_with_free_func (g_free);
priv->profile = as_profile_new ();
priv->settings = g_settings_new ("org.gnome.software");
@@ -3376,6 +3425,7 @@ static void
gs_plugin_loader_cancelled_cb (GCancellable *cancellable, GsPluginLoaderHelper *helper)
{
/* just proxy this forward */
+ g_printerr ("PROXY CANCEL %p -> %p\n", cancellable, helper->cancellable);
g_cancellable_cancel (helper->cancellable);
}
@@ -3404,7 +3454,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
/* check job has valid action */
if (gs_plugin_job_get_action (plugin_job) == GS_PLUGIN_ACTION_UNKNOWN) {
g_autofree gchar *job_str = gs_plugin_job_to_string (plugin_job);
- task = g_task_new (plugin_loader, cancellable_job, callback, user_data);
+ task = create_task (plugin_loader, cancellable_job, callback, user_data);
g_task_return_new_error (task,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
@@ -3417,7 +3467,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
if (action == GS_PLUGIN_ACTION_REMOVE) {
if (remove_app_from_install_queue (plugin_loader, gs_plugin_job_get_app (plugin_job))) {
GsAppList *list = gs_plugin_job_get_list (plugin_job);
- task = g_task_new (plugin_loader, cancellable, callback, user_data);
+ task = create_task (plugin_loader, cancellable, callback, user_data);
g_task_return_pointer (task, g_object_ref (list), (GDestroyNotify) g_object_unref);
return;
}
@@ -3426,7 +3476,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
!gs_plugin_loader_get_network_available (plugin_loader)) {
GsAppList *list = gs_plugin_job_get_list (plugin_job);
add_app_to_install_queue (plugin_loader, gs_plugin_job_get_app (plugin_job));
- task = g_task_new (plugin_loader, cancellable, callback, user_data);
+ task = create_task (plugin_loader, cancellable, callback, user_data);
g_task_return_pointer (task, g_object_ref (list), (GDestroyNotify) g_object_unref);
return;
}
@@ -3480,7 +3530,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
}
/* check required args */
- task = g_task_new (plugin_loader, cancellable_job, callback, user_data);
+ task = create_task (plugin_loader, cancellable_job, callback, user_data);
switch (action) {
case GS_PLUGIN_ACTION_SEARCH:
case GS_PLUGIN_ACTION_SEARCH_FILES:
@@ -3652,6 +3702,20 @@ gs_plugin_loader_get_system_app (GsPluginLoader *plugin_loader)
return gs_plugin_loader_app_create (plugin_loader, "*/*/*/*/system/*");
}
+GCancellable *
+gs_plugin_loader_get_cancellable (GsPluginLoader *plugin_loader, GsApp *app)
+{
+ GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+ for (guint i = 0; i < priv->tasks->len; i++) {
+ GTask *task = g_ptr_array_index (priv->tasks, i);
+ GsPluginLoaderHelper *helper = g_task_get_task_data (task);
+ if (gs_plugin_job_get_app (helper->plugin_job) == app)
+ return helper->cancellable;
+ }
+
+ return NULL;
+}
+
AsProfile *
gs_plugin_loader_get_profile (GsPluginLoader *plugin_loader)
{
diff --git a/lib/gs-plugin-loader.h b/lib/gs-plugin-loader.h
index c4d9921..65b45f8 100644
--- a/lib/gs-plugin-loader.h
+++ b/lib/gs-plugin-loader.h
@@ -103,6 +103,8 @@ AsProfile *gs_plugin_loader_get_profile (GsPluginLoader *plugin_loader);
GsApp *gs_plugin_loader_app_create (GsPluginLoader *plugin_loader,
const gchar *unique_id);
GsApp *gs_plugin_loader_get_system_app (GsPluginLoader *plugin_loader);
+GCancellable *gs_plugin_loader_get_cancellable (GsPluginLoader *plugin_loader,
+ GsApp *app);
/* only useful from the self tests */
void gs_plugin_loader_setup_again (GsPluginLoader *plugin_loader);
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 0eb7426..6069d82 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -1727,6 +1727,8 @@ settings_changed_cb (GsDetailsPage *self,
void
gs_details_page_set_app (GsDetailsPage *self, GsApp *app)
{
+ GCancellable *cancellable;
+
g_return_if_fail (GS_IS_DETAILS_PAGE (self));
g_return_if_fail (GS_IS_APP (app));
@@ -1746,6 +1748,11 @@ gs_details_page_set_app (GsDetailsPage *self, GsApp *app)
/* save app */
g_set_object (&self->app, app);
+ /* retrieve existing transaction */
+ cancellable = gs_plugin_loader_get_cancellable (self->plugin_loader, app);
+ if (cancellable != NULL)
+ g_set_object (&self->cancellable, cancellable);
+
g_signal_connect_object (self->app, "notify::state",
G_CALLBACK (gs_details_page_notify_state_changed_cb),
self, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]