adding handling EINTR to poll to make it more robust

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>
(cherry picked from commit 5e62ba3428)
This commit is contained in:
Royce Lv 2012-07-19 09:49:41 +08:00 committed by Cole Robinson
parent d13b354bf0
commit 9a7bbc246b

View File

@ -178,48 +178,53 @@ class virEventLoopPure:
def run_once(self): def run_once(self):
sleep = -1 sleep = -1
self.runningPoll = True self.runningPoll = True
next = self.next_timeout() try:
debug("Next timeout due at %d" % next) next = self.next_timeout()
if next > 0: 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) now = int(time.time() * 1000)
if now >= next: for t in self.timers:
sleep = 0 interval = t.get_interval()
else: if interval < 0:
sleep = (next - now) / 1000.0 continue
debug("Poll with a sleep of %d" % sleep) want = t.get_last_fired() + interval
events = self.poll.poll(sleep) # 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()
# Dispatch any file handle events that occurred except (os.error, select.error), e:
for (fd, revents) in events: if e.args[0] != errno.EINTR:
# See if the events was from the self-pipe raise
# telling us to wakup. if so, then discard finally:
# the data just continue self.runningPoll = False
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
# Actually the event loop forever # Actually the event loop forever