[gnome-boxes] libvirt-broker: Don't add domain twice



commit 62abbde1698d83d1e9cd4b7ab8444b5f895db8de
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Wed Jul 8 17:52:28 2015 +0100

    libvirt-broker: Don't add domain twice
    
    When Boxes creates a new libvirt domain, LibvirtBroker.add_domain() gets
    called twice for it, once as a result of signal from libvirt that a new
    domain has been added and then by VMCreator as part of box creation.
    This was not a problem until LibvirtMachine constructor became async,
    since Machine would be created before first add_domain() call returns and
    hence the second call would see Machine already existing and would return
    without doing anything.
    
    With this patch, we now keep a list of pending domains and if domain
    being added is in that list, add_domain() simply waits untill domain has
    been added by previous call and return the associated Machine once it's
    done.

 src/libvirt-broker.vala |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)
---
diff --git a/src/libvirt-broker.vala b/src/libvirt-broker.vala
index 348c530..62c02cd 100644
--- a/src/libvirt-broker.vala
+++ b/src/libvirt-broker.vala
@@ -5,6 +5,7 @@ using Gtk;
 private class Boxes.LibvirtBroker : Boxes.Broker {
     private static LibvirtBroker broker;
     private HashTable<string,GVir.Connection> connections;
+    private GLib.List<GVir.Domain> pending_domains;
 
     public static LibvirtBroker get_default () {
         if (broker == null)
@@ -15,6 +16,7 @@ private class Boxes.LibvirtBroker : Boxes.Broker {
 
     private LibvirtBroker () {
         connections = new HashTable<string, GVir.Connection> (str_hash, str_equal);
+        pending_domains = new GLib.List<GVir.Domain> ();
     }
 
     public GVir.Connection get_connection (string name) {
@@ -26,14 +28,32 @@ private class Boxes.LibvirtBroker : Boxes.Broker {
                                             throws GLib.Error {
         return_if_fail (broker != null);
 
+        if (pending_domains.find (domain) != null) {
+            // Already being added asychronously
+            SourceFunc callback = add_domain.callback;
+            ulong id = 0;
+            id = App.app.collection.item_added.connect ((item) => {
+                if (!(item is LibvirtMachine) || (item as LibvirtMachine).domain != domain)
+                    return;
+
+                App.app.collection.disconnect (id);
+                callback ();
+            });
+
+            yield;
+        }
+
         var machine = domain.get_data<LibvirtMachine> ("machine");
         if (machine != null)
             return machine; // Already added
 
+        pending_domains.append (domain);
         machine = yield new LibvirtMachine (source, connection, domain);
+        pending_domains.remove (domain);
+
         machine.suspend_at_exit = (connection == App.app.default_connection);
-        App.app.collection.add_item (machine);
         domain.set_data<LibvirtMachine> ("machine", machine);
+        App.app.collection.add_item (machine);
 
         if (source.name != App.DEFAULT_SOURCE_NAME)
             return machine;


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