c2ca854
commit 13dd371e4840b8dca70508477cfc6820ac5d9a71
c2ca854
Author: Cole Robinson <crobinso@redhat.com>
c2ca854
Date:   Wed Feb 8 14:15:15 2012 -0500
c2ca854
c2ca854
    Don't let media polling block app if a connection goes down
c2ca854
    
c2ca854
    If we unplug a remote machine we are connected to, doing the media
c2ca854
    timeout with a gobject timeout means running it in the main thread,
c2ca854
    which if it's blocking on the remote connection will freeze the whole
c2ca854
    app.
c2ca854
c2ca854
diff --git a/src/virtManager/connection.py b/src/virtManager/connection.py
c2ca854
index 15c1d5e..d649c44 100644
c2ca854
--- a/src/virtManager/connection.py
c2ca854
+++ b/src/virtManager/connection.py
c2ca854
@@ -1583,6 +1583,9 @@ class vmmConnection(vmmGObject):
c2ca854
                                   "connection doesn't seem to have dropped. "
c2ca854
                                   "Ignoring.")
c2ca854
 
c2ca854
+        for dev in self.mediadevs.values():
c2ca854
+            dev.tick()
c2ca854
+
c2ca854
         if not noStatsUpdate:
c2ca854
             self._recalculate_stats(now, updateVMs)
c2ca854
 
c2ca854
diff --git a/src/virtManager/mediadev.py b/src/virtManager/mediadev.py
c2ca854
index 3731599..a046d9e 100644
c2ca854
--- a/src/virtManager/mediadev.py
c2ca854
+++ b/src/virtManager/mediadev.py
c2ca854
@@ -19,6 +19,7 @@
c2ca854
 #
c2ca854
 
c2ca854
 import logging
c2ca854
+import time
c2ca854
 
c2ca854
 import virtinst
c2ca854
 
c2ca854
@@ -49,7 +50,7 @@ class vmmMediaDevice(vmmGObject):
c2ca854
 
c2ca854
         obj = vmmMediaDevice(path, key, has_media, media_label, media_key,
c2ca854
                              dev, drvtype)
c2ca854
-        obj.enable_poll_for_media()
c2ca854
+        obj.do_poll = True
c2ca854
 
c2ca854
         return obj
c2ca854
 
c2ca854
@@ -65,7 +66,8 @@ class vmmMediaDevice(vmmGObject):
c2ca854
         self.media_type = media_type
c2ca854
 
c2ca854
         self.nodedev_obj = nodedev_obj
c2ca854
-        self.poll_signal = None
c2ca854
+        self.do_poll = False
c2ca854
+        self.last_tick = 0
c2ca854
 
c2ca854
     def _cleanup(self):
c2ca854
         pass
c2ca854
@@ -130,50 +132,38 @@ class vmmMediaDevice(vmmGObject):
c2ca854
     #########################################
c2ca854
     # Nodedev API polling for media updates #
c2ca854
     #########################################
c2ca854
-    def enable_poll_for_media(self):
c2ca854
-        if self.poll_signal:
c2ca854
-            return
c2ca854
-
c2ca854
-        self.poll_signal = self.safe_timeout_add(MEDIA_TIMEOUT * 1000,
c2ca854
-                                                 self._poll_for_media)
c2ca854
-        self.add_gobject_timeout(self.poll_signal)
c2ca854
-
c2ca854
-    def disable_poll_for_media(self):
c2ca854
-        self.remove_gobject_timeout(self.poll_signal)
c2ca854
-        self.poll_signal = None
c2ca854
-
c2ca854
-    def _poll_for_media(self):
c2ca854
-        if not self.poll_signal:
c2ca854
-            return False
c2ca854
 
c2ca854
+    def tick(self):
c2ca854
         if not self.nodedev_obj:
c2ca854
-            return False
c2ca854
+            return
c2ca854
 
c2ca854
         if not self.nodedev_obj.conn.is_active():
c2ca854
-            return False
c2ca854
+            return
c2ca854
+
c2ca854
+        if (time.time() - self.last_tick) < MEDIA_TIMEOUT:
c2ca854
+            return
c2ca854
+        self.last_tick = time.time()
c2ca854
 
c2ca854
         try:
c2ca854
             self.nodedev_obj.refresh_xml()
c2ca854
             xml = self.nodedev_obj.get_xml()
c2ca854
         except:
c2ca854
             # Assume the device was removed
c2ca854
-            return False
c2ca854
+            return
c2ca854
 
c2ca854
         try:
c2ca854
             vobj = virtinst.NodeDeviceParser.parse(xml)
c2ca854
             has_media = vobj.media_available
c2ca854
         except:
c2ca854
             logging.exception("Node device CDROM polling failed")
c2ca854
-            return False
c2ca854
+            return
c2ca854
+
c2ca854
+        if has_media == self.has_media():
c2ca854
+            return
c2ca854
 
c2ca854
-        if has_media != self.has_media():
c2ca854
-            self.set_media(has_media, None, None)
c2ca854
-            if has_media:
c2ca854
-                self.emit("media-added")
c2ca854
-            else:
c2ca854
-                self.emit("media-removed")
c2ca854
+        self.set_media(has_media, None, None)
c2ca854
+        self.idle_emit(has_media and "media-added" or "media-removed")
c2ca854
 
c2ca854
-        return True
c2ca854
 
c2ca854
 vmmGObject.type_register(vmmMediaDevice)
c2ca854
 vmmMediaDevice.signal_new(vmmMediaDevice, "media-added", [])