[libvirt] [PATCHv2] adding handling EINTR to poll to make it more robust

lvroyce at linux.vnet.ibm.com lvroyce at linux.vnet.ibm.com
Tue Jun 19 06:23:49 UTC 2012


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

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 at linux.vnet.ibm.com>
---
 examples/domain-events/events-python/event-test.py |   95 +++++++++++---------
 1 files changed, 51 insertions(+), 44 deletions(-)

diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 96dc268..7832d13 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -2,9 +2,9 @@
 #
 #
 #
-#################################################################################
+##############################################################################
 # Start off by implementing a general purpose event loop for anyones use
-#################################################################################
+##############################################################################
 
 import sys
 import getopt
@@ -27,11 +27,14 @@ import threading
 use_pure_python_event_loop = True
 
 do_debug = False
+
+
 def debug(msg):
     global do_debug
     if do_debug:
         print msg
 
+
 #
 # This general purpose event loop will support waiting for file handle
 # I/O and errors events, as well as scheduling repeatable timers with
@@ -97,7 +100,6 @@ class virEventLoopPure:
             self.cb(self.timer,
                     self.opaque)
 
-
     def __init__(self):
         self.poll = select.poll()
         self.pipetrick = os.pipe()
@@ -178,48 +180,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))
+        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))
 
-        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 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 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()
+
+        except (os.error, select.error), e:
+            if e.errno != errno.EINTR:
+                raise
+        finally:
+            self.runningPoll = False
 
 
     # Actually the event loop forever
-- 
1.7.7.6




More information about the libvir-list mailing list