diff options
-rw-r--r-- | src/application-service-appstore.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c index 3e827d5..9d35d66 100644 --- a/src/application-service-appstore.c +++ b/src/application-service-appstore.c @@ -110,6 +110,7 @@ struct _Application { gchar * guide; gboolean currently_free; guint ordering_index; + GList * approver_cancels; GList * approved_by; visible_state_t visible_state; guint name_watcher; @@ -745,6 +746,11 @@ application_free (Application * app) if (app->guide != NULL) { g_free(app->guide); } + if (app->approver_cancels != NULL) { + g_list_foreach(app->approver_cancels, (GFunc)g_cancellable_cancel, NULL); + g_list_foreach(app->approver_cancels, (GFunc)g_object_unref, NULL); + g_list_free(app->approver_cancels); + } if (app->approved_by != NULL) { g_list_free(app->approved_by); } @@ -997,6 +1003,7 @@ application_service_appstore_application_add (ApplicationServiceAppstore * appst app->guide = NULL; app->currently_free = FALSE; app->ordering_index = 0; + app->approver_cancels = NULL; app->approved_by = NULL; app->visible_state = VISIBLE_STATE_HIDDEN; app->name_watcher = 0; @@ -1283,6 +1290,24 @@ static void remove_approver (gpointer papp, gpointer pproxy) { Application * app = (Application *)papp; + + /* Check for any pending approvals and cancel them */ + GList * iter = app->approver_cancels; + while (iter != NULL) { + GCancellable * cancel = (GCancellable *)iter->data; + GDBusProxy * proxy = (GDBusProxy *)g_object_get_data(G_OBJECT(cancel), "proxy"); + if (proxy == pproxy) { + g_cancellable_cancel(cancel); + g_object_unref(cancel); + + GList * next = iter->next; + app->approver_cancels = g_list_delete_link(app->approver_cancels, iter); + iter = next; + } else { + iter = iter->next; + } + } + app->approved_by = g_list_remove(app->approved_by, pproxy); apply_status(app); return; @@ -1323,19 +1348,29 @@ static void approver_request_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GDBusProxy * proxy = G_DBUS_PROXY(object); - Application * app = (Application *)user_data; + GCancellable * cancel = (GCancellable *)user_data; GError * error = NULL; gboolean approved = TRUE; /* default to approved */ GVariant * result; result = g_dbus_proxy_call_finish(proxy, res, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (error); + return; // Must exit before accessing freed memory + } + + Application * app = (Application *)g_object_get_data(G_OBJECT(cancel), "app"); + app->approver_cancels = g_list_remove(app->approver_cancels, cancel); + g_object_unref(cancel); + if (error == NULL) { g_variant_get(result, "(b)", &approved); g_debug("Approver responded: %s", approved ? "approve" : "rejected"); } else { g_debug("Approver responded error: %s", error->message); + g_error_free (error); } if (approved) { @@ -1354,12 +1389,18 @@ check_with_new_approver (gpointer papp, gpointer papprove) { Application * app = (Application *)papp; Approver * approver = (Approver *)papprove; + GCancellable * cancel = NULL; + + cancel = g_cancellable_new(); + g_object_set_data(G_OBJECT(cancel), "app", app); + g_object_set_data(G_OBJECT(cancel), "proxy", approver->proxy); + app->approver_cancels = g_list_prepend(app->approver_cancels, cancel); g_dbus_proxy_call(approver->proxy, "ApproveItem", g_variant_new("(ssuso)", app->id, app->category, 0, app->dbus_name, app->dbus_object), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, - approver_request_cb, app); + G_DBUS_CALL_FLAGS_NONE, -1, cancel, + approver_request_cb, cancel); return; } |