[libvirt] [PATCH] 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> --- examples/domain-events/events-python/event-test.py | 87 +++++++++++--------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py index 96dc268..6b655cd 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -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 -- 1.7.10.4

On Thu, Jul 19, 2012 at 09:49:41AM +0800, Royce Lv wrote:
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 | 87 +++++++++++--------- 1 file changed, 46 insertions(+), 41 deletions(-)
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py index 96dc268..6b655cd 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -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
Thanks, I'm happy with this version.

On 07/22/2012 09:01 AM, Dan Kenigsberg wrote:
On Thu, Jul 19, 2012 at 09:49:41AM +0800, Royce Lv wrote:
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>
Thanks, I'm happy with this version.
Pushed. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (3)
-
Dan Kenigsberg
-
Eric Blake
-
Royce Lv