]> xenbits.xensource.com Git - libvirt.git/commitdiff
adding handling EINTR to poll to make it more robust
authorRoyce Lv <lvroyce@linux.vnet.ibm.com>
Thu, 19 Jul 2012 01:49:41 +0000 (09:49 +0800)
committerEric Blake <eblake@redhat.com>
Mon, 23 Jul 2012 23:40:21 +0000 (17:40 -0600)
some system call and signal will interrupt poll,
making event loop stops and fails to react events and keepalive message
from libvirt.
adding handling EINTR to poll to make it more robust

Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com>
examples/domain-events/events-python/event-test.py

index 137c31c8872d45f5321fbbbfa71c61c80e9ec498..736c225a4def6c5902cbe3be882df7c4a418b60f 100644 (file)
@@ -178,48 +178,53 @@ class virEventLoopPure:
     def run_once(self):
         sleep = -1
         self.runningPoll = True
-        next = self.next_timeout()
-        debug("Next timeout due at %d" % next)
-        if next > 0:
-            now = int(time.time() * 1000)
-            if now >= next:
-                sleep = 0
-            else:
-                sleep = (next - now) / 1000.0
-
-        debug("Poll with a sleep of %d" % sleep)
-        events = self.poll.poll(sleep)
-
-        # Dispatch any file handle events that occurred
-        for (fd, revents) in events:
-            # See if the events was from the self-pipe
-            # telling us to wakup. if so, then discard
-            # the data just continue
-            if fd == self.pipetrick[0]:
-                self.pendingWakeup = False
-                data = os.read(fd, 1)
-                continue
-
-            h = self.get_handle_by_fd(fd)
-            if h:
-                debug("Dispatch fd %d handle %d events %d" % (fd, h.get_id(), revents))
-                h.dispatch(self.events_from_poll(revents))
-
-        now = int(time.time() * 1000)
-        for t in self.timers:
-            interval = t.get_interval()
-            if interval < 0:
-                continue
+        try:
+            next = self.next_timeout()
+            debug("Next timeout due at %d" % next)
+            if next > 0:
+                now = int(time.time() * 1000)
+                if now >= next:
+                    sleep = 0
+                else:
+                    sleep = (next - now) / 1000.0
+
+            debug("Poll with a sleep of %d" % sleep)
+            events = self.poll.poll(sleep)
+
+            # Dispatch any file handle events that occurred
+            for (fd, revents) in events:
+                # See if the events was from the self-pipe
+                # telling us to wakup. if so, then discard
+                # the data just continue
+                if fd == self.pipetrick[0]:
+                    self.pendingWakeup = False
+                    data = os.read(fd, 1)
+                    continue
+
+                h = self.get_handle_by_fd(fd)
+                if h:
+                    debug("Dispatch fd %d handle %d events %d" % (fd, h.get_id(), revents))
+                    h.dispatch(self.events_from_poll(revents))
 
-            want = t.get_last_fired() + interval
-            # Deduct 20ms, since schedular timeslice
-            # means we could be ever so slightly early
-            if now >= (want-20):
-                debug("Dispatch timer %d now %s want %s" % (t.get_id(), str(now), str(want)))
-                t.set_last_fired(now)
-                t.dispatch()
-
-        self.runningPoll = False
+            now = int(time.time() * 1000)
+            for t in self.timers:
+                interval = t.get_interval()
+                if interval < 0:
+                    continue
+
+                want = t.get_last_fired() + interval
+                # Deduct 20ms, since scheduler timeslice
+                # means we could be ever so slightly early
+                if now >= (want-20):
+                    debug("Dispatch timer %d now %s want %s" % (t.get_id(), str(now), str(want)))
+                    t.set_last_fired(now)
+                    t.dispatch()
+
+        except (os.error, select.error), e:
+            if e.args[0] != errno.EINTR:
+                raise
+        finally:
+            self.runningPoll = False
 
 
     # Actually the event loop forever