[gnome-boxes] Wait until all machines are suspended



commit 0c46399c9915b900cb612efcb8482fda0fba5395
Author: Christophe Fergeau <cfergeau redhat com>
Date:   Fri Sep 14 15:17:16 2012 +0200

    Wait until all machines are suspended
    
    We need to wait until all suspend() calls are finished to be sure
    that the call went through. We shouldn't hold the app though, so
    it needs to be done in a seperate loop when the program exits.
    
    Based on a patch from Marc-Andrà Lureau <marcandre lureau gmail com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683473

 src/app.vala  |   43 ++++++++++++++++++++++++++++++++++++-------
 src/main.vala |    7 ++++++-
 2 files changed, 42 insertions(+), 8 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index 8d6edae..946ee37 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -160,6 +160,13 @@ private class Boxes.App: Boxes.UI {
         return application.run ();
     }
 
+    // To be called to tell App to release the resources it's handling.
+    // Currently this only releases the GtkApplication we use, but
+    // more shutdown work could be done here in the future
+    public void shutdown () {
+        application = null;
+    }
+
     public void open (string name) {
         ui_state = UIState.COLLECTION;
         // we don't want to show the collection items as it will
@@ -565,19 +572,41 @@ private class Boxes.App: Boxes.UI {
         }
     }
 
-    public bool quit () {
-        notificationbar.cancel ();
-        save_window_geometry ();
-        window.hide ();
+    public void suspend_machines () {
+        debug ("Suspending running boxes");
+
+        var waiting_counter = 0;
+        // use a private main context to suspend the VMs to avoid
+        // DBus or other callbacks being fired while we suspend
+        // the VMs during Boxes shutdown.
+        var context = new MainContext ();
 
-        foreach (var item in collection.items.data)
+        context.push_thread_default ();
+        foreach (var item in collection.items.data) {
             if (item is LibvirtMachine) {
                 var machine = item as LibvirtMachine;
 
-                if (machine.suspend_at_exit)
-                    machine.suspend.begin ();
+                if (machine.suspend_at_exit) {
+                    waiting_counter++;
+                    machine.suspend.begin (() => {
+                            debug ("%s suspended", machine.name);
+                            waiting_counter--;
+                    });
+                }
             }
+        }
+        context.pop_thread_default ();
+
+        // wait for async methods to complete
+        while (waiting_counter > 0)
+            context.iteration (true);
+
+        debug ("Running boxes suspended");
+    }
 
+    public bool quit () {
+        notificationbar.cancel ();
+        save_window_geometry ();
         wizard.cleanup ();
         window.destroy ();
 
diff --git a/src/main.vala b/src/main.vala
index 9ada8fd..657af10 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -130,5 +130,10 @@ public int main (string[] args) {
         app.fullscreen = fullscreen;
     });
 
-    return app.run ();
+    var exit_status = app.run ();
+
+    app.shutdown ();
+    app.suspend_machines ();
+
+    return exit_status;
 }



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