[virt-tools-list] [PATCH virt-viewer v4 12/12] ovirt-foreign-menu: Fetch ISO names using GTask API

Eduardo Lima (Etrunko) etrunko at redhat.com
Tue Nov 1 20:33:42 UTC 2016


Similar to the previous commit, the ISO dialog will fetch the result
asynchronously, rather than relying on the "notify::files" signal from
OvirtForeignMenu object. It also enables error to be shown if anything
goes wrong.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko at redhat.com>
---
 src/ovirt-foreign-menu.c            | 140 ++++++++++++++++++++++--------------
 src/ovirt-foreign-menu.h            |   9 ++-
 src/remote-viewer-iso-list-dialog.c |  45 ++++++------
 3 files changed, 117 insertions(+), 77 deletions(-)

diff --git a/src/ovirt-foreign-menu.c b/src/ovirt-foreign-menu.c
index 288a812..51d8ece 100644
--- a/src/ovirt-foreign-menu.c
+++ b/src/ovirt-foreign-menu.c
@@ -40,13 +40,13 @@ typedef enum {
     STATE_ISOS
 } OvirtForeignMenuState;
 
-static void ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu, OvirtForeignMenuState state);
-static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu);
-static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu);
-static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu);
-static void ovirt_foreign_menu_fetch_vm_cdrom_async(OvirtForeignMenu *menu);
-static void ovirt_foreign_menu_refresh_cdrom_file_async(OvirtForeignMenu *menu);
-static void ovirt_foreign_menu_fetch_iso_list_async(OvirtForeignMenu *menu);
+static void ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu, GTask *task, OvirtForeignMenuState state);
+static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu, GTask *task);
+static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu, GTask *task);
+static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu, GTask *task);
+static void ovirt_foreign_menu_fetch_vm_cdrom_async(OvirtForeignMenu *menu, GTask *task);
+static void ovirt_foreign_menu_refresh_cdrom_file_async(OvirtForeignMenu *menu, GTask *task);
+static void ovirt_foreign_menu_fetch_iso_list_async(OvirtForeignMenu *menu, GTask *task);
 static void iso_name_set_cb(GObject *source_object, GAsyncResult *result, gpointer user_data);
 
 G_DEFINE_TYPE (OvirtForeignMenu, ovirt_foreign_menu, G_TYPE_OBJECT)
@@ -319,11 +319,9 @@ OvirtForeignMenu* ovirt_foreign_menu_new(OvirtProxy *proxy)
 
 static void
 ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu,
+                                   GTask *task,
                                    OvirtForeignMenuState current_state)
 {
-    g_return_if_fail(current_state >= STATE_0);
-    g_return_if_fail(current_state < STATE_ISOS);
-
     /* Each state will check if the member is initialized, falling directly to
      * the next one if so. If not, the callback for the asynchronous call will
      * be responsible for calling is function again with the next state as
@@ -332,26 +330,26 @@ ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu,
     switch (current_state + 1) {
     case STATE_API:
         if (menu->priv->api == NULL) {
-            ovirt_foreign_menu_fetch_api_async(menu);
+            ovirt_foreign_menu_fetch_api_async(menu, task);
             break;
         }
     case STATE_VM:
         if (menu->priv->vm == NULL) {
-            ovirt_foreign_menu_fetch_vm_async(menu);
+            ovirt_foreign_menu_fetch_vm_async(menu, task);
             break;
         }
     case STATE_STORAGE_DOMAIN:
         if (menu->priv->files == NULL) {
-            ovirt_foreign_menu_fetch_storage_domain_async(menu);
+            ovirt_foreign_menu_fetch_storage_domain_async(menu, task);
             break;
         }
     case STATE_VM_CDROM:
         if (menu->priv->cdrom == NULL) {
-            ovirt_foreign_menu_fetch_vm_cdrom_async(menu);
+            ovirt_foreign_menu_fetch_vm_cdrom_async(menu, task);
             break;
         }
     case STATE_CDROM_FILE:
-        ovirt_foreign_menu_refresh_cdrom_file_async(menu);
+        ovirt_foreign_menu_refresh_cdrom_file_async(menu, task);
         break;
     case STATE_ISOS:
         g_warn_if_fail(menu->priv->api != NULL);
@@ -359,18 +357,36 @@ ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu,
         g_warn_if_fail(menu->priv->files != NULL);
         g_warn_if_fail(menu->priv->cdrom != NULL);
 
-        ovirt_foreign_menu_fetch_iso_list_async(menu);
+        ovirt_foreign_menu_fetch_iso_list_async(menu, task);
         break;
     default:
         g_warn_if_reached();
+        g_task_return_new_error(task, OVIRT_ERROR, OVIRT_ERROR_FAILED,
+                                "Invalid state: %d", current_state);
+        g_object_unref(task);
     }
 }
 
 
 void
-ovirt_foreign_menu_start(OvirtForeignMenu *menu)
+ovirt_foreign_menu_fetch_iso_names_async(OvirtForeignMenu *menu,
+                                         GCancellable *cancellable,
+                                         GAsyncReadyCallback callback,
+                                         gpointer user_data)
+
 {
-    ovirt_foreign_menu_next_async_step(menu, STATE_0);
+    GTask *task = g_task_new(menu, cancellable, callback, user_data);
+    ovirt_foreign_menu_next_async_step(menu, task, STATE_0);
+}
+
+
+GList *
+ovirt_foreign_menu_fetch_iso_names_finish(OvirtForeignMenu *foreign_menu,
+                                          GAsyncResult *result,
+                                          GError **error)
+{
+    g_return_val_if_fail(OVIRT_IS_FOREIGN_MENU(foreign_menu), NULL);
+    return g_task_propagate_pointer(G_TASK(result), error);
 }
 
 
@@ -439,7 +455,6 @@ static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu,
 
     g_list_free_full(menu->priv->iso_names, (GDestroyNotify)g_free);
     menu->priv->iso_names = sorted_files;
-    g_object_notify(G_OBJECT(menu), "files");
 }
 
 
@@ -448,13 +463,15 @@ static void cdrom_file_refreshed_cb(GObject *source_object,
                                     gpointer user_data)
 {
     OvirtResource *cdrom  = OVIRT_RESOURCE(source_object);
-    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
     GError *error = NULL;
 
     ovirt_resource_refresh_finish(cdrom, result, &error);
     if (error != NULL) {
         g_warning("failed to refresh cdrom content: %s", error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
 
@@ -467,20 +484,21 @@ static void cdrom_file_refreshed_cb(GObject *source_object,
     }
     g_object_notify(G_OBJECT(menu), "file");
     if (menu->priv->cdrom != NULL) {
-        ovirt_foreign_menu_next_async_step(menu, STATE_CDROM_FILE);
+        ovirt_foreign_menu_next_async_step(menu, task, STATE_CDROM_FILE);
     } else {
         g_debug("Could not find VM cdrom through oVirt REST API");
     }
 }
 
 
-static void ovirt_foreign_menu_refresh_cdrom_file_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_refresh_cdrom_file_async(OvirtForeignMenu *menu,
+                                                        GTask *task)
 {
     g_return_if_fail(OVIRT_IS_RESOURCE(menu->priv->cdrom));
 
     ovirt_resource_refresh_async(OVIRT_RESOURCE(menu->priv->cdrom),
                                  menu->priv->proxy, NULL,
-                                 cdrom_file_refreshed_cb, menu);
+                                 cdrom_file_refreshed_cb, task);
 }
 
 
@@ -490,7 +508,8 @@ static void cdroms_fetched_cb(GObject *source_object,
 {
     GHashTable *cdroms;
     OvirtCollection *cdrom_collection = OVIRT_COLLECTION(source_object);
-    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
     GHashTableIter iter;
     OvirtCdrom *cdrom;
     GError *error = NULL;
@@ -498,7 +517,8 @@ static void cdroms_fetched_cb(GObject *source_object,
     ovirt_collection_fetch_finish(cdrom_collection, result, &error);
     if (error != NULL) {
         g_warning("failed to fetch cdrom collection: %s", error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
 
@@ -520,20 +540,21 @@ static void cdroms_fetched_cb(GObject *source_object,
     }
 
     if (menu->priv->cdrom != NULL) {
-        ovirt_foreign_menu_next_async_step(menu, STATE_VM_CDROM);
+        ovirt_foreign_menu_next_async_step(menu, task, STATE_VM_CDROM);
     } else {
         g_debug("Could not find VM cdrom through oVirt REST API");
     }
 }
 
 
-static void ovirt_foreign_menu_fetch_vm_cdrom_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_fetch_vm_cdrom_async(OvirtForeignMenu *menu,
+                                                    GTask *task)
 {
     OvirtCollection *cdrom_collection;
 
     cdrom_collection = ovirt_vm_get_cdroms(menu->priv->vm);
     ovirt_collection_fetch_async(cdrom_collection, menu->priv->proxy, NULL,
-                                 cdroms_fetched_cb, menu);
+                                 cdroms_fetched_cb, task);
 }
 
 
@@ -542,7 +563,8 @@ static void storage_domains_fetched_cb(GObject *source_object,
                                        gpointer user_data)
 {
     GError *error = NULL;
-    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
     OvirtCollection *collection = OVIRT_COLLECTION(source_object);
     GHashTableIter iter;
     OvirtStorageDomain *domain;
@@ -550,7 +572,8 @@ static void storage_domains_fetched_cb(GObject *source_object,
     ovirt_collection_fetch_finish(collection, result, &error);
     if (error != NULL) {
         g_warning("failed to fetch storage domains: %s", error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
 
@@ -581,21 +604,21 @@ static void storage_domains_fetched_cb(GObject *source_object,
     }
 
     if (menu->priv->files != NULL) {
-        ovirt_foreign_menu_next_async_step(menu, STATE_STORAGE_DOMAIN);
+        ovirt_foreign_menu_next_async_step(menu, task, STATE_STORAGE_DOMAIN);
     } else {
         g_debug("Could not find iso file collection");
     }
 }
 
 
-static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu,
+                                                          GTask *task)
 {
-    OvirtCollection *collection;
+    OvirtCollection *collection = ovirt_api_get_storage_domains(menu->priv->api);
 
     g_debug("Start fetching oVirt REST collection");
-    collection = ovirt_api_get_storage_domains(menu->priv->api);
     ovirt_collection_fetch_async(collection, menu->priv->proxy, NULL,
-                                 storage_domains_fetched_cb, menu);
+                                 storage_domains_fetched_cb, task);
 }
 
 
@@ -604,16 +627,17 @@ static void vms_fetched_cb(GObject *source_object,
                            gpointer user_data)
 {
     GError *error = NULL;
-    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
-    OvirtCollection *collection;
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
+    OvirtCollection *collection = OVIRT_COLLECTION(source_object);
     GHashTableIter iter;
     OvirtVm *vm;
 
-    collection = OVIRT_COLLECTION(source_object);
     ovirt_collection_fetch_finish(collection, result, &error);
     if (error != NULL) {
         g_debug("failed to fetch VM list: %s", error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
 
@@ -630,14 +654,15 @@ static void vms_fetched_cb(GObject *source_object,
         g_free(guid);
     }
     if (menu->priv->vm != NULL) {
-        ovirt_foreign_menu_next_async_step(menu, STATE_VM);
+        ovirt_foreign_menu_next_async_step(menu, task, STATE_VM);
     } else {
         g_warning("failed to find a VM with guid \"%s\"", menu->priv->vm_guid);
     }
 }
 
 
-static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu,
+                                              GTask *task)
 {
     OvirtCollection *vms;
 
@@ -647,7 +672,7 @@ static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu)
 
     vms = ovirt_api_get_vms(menu->priv->api);
     ovirt_collection_fetch_async(vms, menu->priv->proxy,
-                                 NULL, vms_fetched_cb, menu);
+                                 NULL, vms_fetched_cb, task);
 }
 
 
@@ -656,31 +681,33 @@ static void api_fetched_cb(GObject *source_object,
                            gpointer user_data)
 {
     GError *error = NULL;
-    OvirtProxy *proxy;
-    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
+    OvirtProxy *proxy = OVIRT_PROXY(source_object);
 
-    proxy = OVIRT_PROXY(source_object);
     menu->priv->api = ovirt_proxy_fetch_api_finish(proxy, result, &error);
     if (error != NULL) {
         g_debug("failed to fetch toplevel API object: %s", error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
     g_return_if_fail(OVIRT_IS_API(menu->priv->api));
     g_object_ref(menu->priv->api);
 
-    ovirt_foreign_menu_next_async_step(menu, STATE_API);
+    ovirt_foreign_menu_next_async_step(menu, task, STATE_API);
 }
 
 
-static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu,
+                                               GTask *task)
 {
     g_debug("Start fetching oVirt main entry point");
 
     g_return_if_fail(OVIRT_IS_FOREIGN_MENU(menu));
     g_return_if_fail(OVIRT_IS_PROXY(menu->priv->proxy));
 
-    ovirt_proxy_fetch_api_async(menu->priv->proxy, NULL, api_fetched_cb, menu);
+    ovirt_proxy_fetch_api_async(menu->priv->proxy, NULL, api_fetched_cb, task);
 }
 
 
@@ -688,6 +715,8 @@ static void iso_list_fetched_cb(GObject *source_object,
                                 GAsyncResult *result,
                                 gpointer user_data)
 {
+    GTask *task = G_TASK(user_data);
+    OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(g_task_get_source_object(task));
     OvirtCollection *collection = OVIRT_COLLECTION(source_object);
     GError *error = NULL;
     GList *files;
@@ -696,17 +725,20 @@ static void iso_list_fetched_cb(GObject *source_object,
     if (error != NULL) {
         g_warning("failed to fetch files for ISO storage domain: %s",
                    error->message);
-        g_clear_error(&error);
+        g_task_return_error(task, error);
+        g_object_unref(task);
         return;
     }
 
     files = g_hash_table_get_values(ovirt_collection_get_resources(collection));
-    ovirt_foreign_menu_set_files(OVIRT_FOREIGN_MENU(user_data), files);
+    ovirt_foreign_menu_set_files(menu, files);
     g_list_free(files);
+    g_task_return_pointer(task, menu->priv->iso_names, NULL);
 }
 
 
-static void ovirt_foreign_menu_fetch_iso_list_async(OvirtForeignMenu *menu)
+static void ovirt_foreign_menu_fetch_iso_list_async(OvirtForeignMenu *menu,
+                                                    GTask *task)
 {
     if (menu->priv->files == NULL) {
         return;
@@ -714,7 +746,7 @@ static void ovirt_foreign_menu_fetch_iso_list_async(OvirtForeignMenu *menu)
 
     g_debug("Refreshing foreign menu iso list");
     ovirt_collection_fetch_async(menu->priv->files, menu->priv->proxy,
-                                 NULL, iso_list_fetched_cb, menu);
+                                 NULL, iso_list_fetched_cb, task);
 }
 
 
diff --git a/src/ovirt-foreign-menu.h b/src/ovirt-foreign-menu.h
index df4a50e..6d936ff 100644
--- a/src/ovirt-foreign-menu.h
+++ b/src/ovirt-foreign-menu.h
@@ -68,7 +68,14 @@ GType ovirt_foreign_menu_get_type(void);
 
 OvirtForeignMenu* ovirt_foreign_menu_new(OvirtProxy *proxy);
 OvirtForeignMenu *ovirt_foreign_menu_new_from_file(VirtViewerFile *self);
-void ovirt_foreign_menu_start(OvirtForeignMenu *menu);
+
+void ovirt_foreign_menu_fetch_iso_names_async(OvirtForeignMenu *menu,
+                                              GCancellable *cancellable,
+                                              GAsyncReadyCallback callback,
+                                              gpointer user_data);
+GList *ovirt_foreign_menu_fetch_iso_names_finish(OvirtForeignMenu *foreign_menu,
+                                                 GAsyncResult *result,
+                                                 GError **error);
 
 char *ovirt_foreign_menu_get_current_iso_name(OvirtForeignMenu *menu);
 void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_menu,
diff --git a/src/remote-viewer-iso-list-dialog.c b/src/remote-viewer-iso-list-dialog.c
index b374b89..2de7b8a 100644
--- a/src/remote-viewer-iso-list-dialog.c
+++ b/src/remote-viewer-iso-list-dialog.c
@@ -126,15 +126,19 @@ remote_viewer_iso_list_dialog_foreach(char *name, RemoteViewerISOListDialog *sel
 }
 
 static void
-remote_viewer_iso_list_dialog_refresh_iso_list(RemoteViewerISOListDialog *self,
-                                               gboolean refreshing)
+fetch_iso_names_cb(OvirtForeignMenu *foreign_menu,
+                   GAsyncResult *result,
+                   RemoteViewerISOListDialog *self)
 {
     RemoteViewerISOListDialogPrivate *priv = self->priv;
+    GError *error = NULL;
     GList *iso_list;
 
-    if (refreshing) {
-        gtk_list_store_clear(priv->list_store);
-        ovirt_foreign_menu_start(priv->foreign_menu);
+    iso_list = ovirt_foreign_menu_fetch_iso_names_finish(foreign_menu, result, &error);
+
+    if (!iso_list) {
+        remote_viewer_iso_list_dialog_show_error(self, error ? error->message : _("Failed to fetch CD names"));
+        g_clear_error(&error);
         return;
     }
 
@@ -143,6 +147,18 @@ remote_viewer_iso_list_dialog_refresh_iso_list(RemoteViewerISOListDialog *self,
     remote_viewer_iso_list_dialog_show_files(self);
 }
 
+
+static void
+remote_viewer_iso_list_dialog_refresh_iso_list(RemoteViewerISOListDialog *self)
+{
+    RemoteViewerISOListDialogPrivate *priv = self->priv;
+
+    gtk_list_store_clear(priv->list_store);
+    ovirt_foreign_menu_fetch_iso_names_async(priv->foreign_menu, NULL,
+                                             (GAsyncReadyCallback) fetch_iso_names_cb,
+                                             self);
+}
+
 static void
 remote_viewer_iso_list_dialog_response(GtkDialog *dialog,
                                        gint response_id,
@@ -158,7 +174,7 @@ remote_viewer_iso_list_dialog_response(GtkDialog *dialog,
     gtk_stack_set_visible_child_full(GTK_STACK(priv->stack), "status",
                                      GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT);
     gtk_dialog_set_response_sensitive(GTK_DIALOG(self), GTK_RESPONSE_NONE, FALSE);
-    remote_viewer_iso_list_dialog_refresh_iso_list(self, TRUE);
+    remote_viewer_iso_list_dialog_refresh_iso_list(self);
 }
 
 void
@@ -301,15 +317,6 @@ end:
     free(current_iso);
 }
 
-static void
-ovirt_foreign_menu_notify_files(OvirtForeignMenu *foreign_menu G_GNUC_UNUSED,
-                                GParamSpec *pspec G_GNUC_UNUSED,
-                                RemoteViewerISOListDialog *self)
-{
-    remote_viewer_iso_list_dialog_refresh_iso_list(self, FALSE);
-}
-
-
 GtkWidget *
 remote_viewer_iso_list_dialog_new(GtkWindow *parent, GObject *foreign_menu)
 {
@@ -329,12 +336,6 @@ remote_viewer_iso_list_dialog_new(GtkWindow *parent, GObject *foreign_menu)
 
     self = REMOTE_VIEWER_ISO_LIST_DIALOG(dialog);
     self->priv->foreign_menu = OVIRT_FOREIGN_MENU(g_object_ref(foreign_menu));
-
-    g_signal_connect(foreign_menu,
-                     "notify::files",
-                     (GCallback)ovirt_foreign_menu_notify_files,
-                     dialog);
-
-    remote_viewer_iso_list_dialog_refresh_iso_list(self, TRUE);
+    remote_viewer_iso_list_dialog_refresh_iso_list(self);
     return dialog;
 }
-- 
2.7.4




More information about the virt-tools-list mailing list