]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Prevent overfilling of self-pipe in python event loop
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 27 Jan 2011 12:54:27 +0000 (12:54 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 28 Jan 2011 11:48:27 +0000 (11:48 +0000)
If the event loop takes a very long time todo something, it is
possible for the 'self pipe' buffer to become full at which
point the entire event loop + remote driver deadlock. Use a
boolean flag to ensure we have strict one-in, one-out behaviour
on writes/reads of the 'self pipe'

examples/domain-events/events-python/event-test.py

index 903f934b2f98ce77b06c2dc1736bfaa337b1d375..c149ed93b8997959ab4d0ca58cfaf00f5a00a261 100644 (file)
@@ -92,6 +92,8 @@ class virEventLoopPure:
     def __init__(self):
         self.poll = select.poll()
         self.pipetrick = os.pipe()
+        self.pendingWakeup = False
+        self.runningPoll = False
         self.nextHandleID = 1
         self.nextTimerID = 1
         self.handles = []
@@ -166,6 +168,7 @@ class virEventLoopPure:
     # these pointless repeated tiny sleeps.
     def run_once(self):
         sleep = -1
+        self.runningPoll = True
         next = self.next_timeout()
         debug("Next timeout due at %d" % next)
         if next > 0:
@@ -184,6 +187,7 @@ class virEventLoopPure:
             # 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
 
@@ -206,6 +210,8 @@ class virEventLoopPure:
                 t.set_last_fired(now)
                 t.dispatch()
 
+        self.runningPoll = False
+
 
     # Actually the event loop forever
     def run_loop(self):
@@ -214,7 +220,9 @@ class virEventLoopPure:
             self.run_once()
 
     def interrupt(self):
-        os.write(self.pipetrick[1], 'c')
+        if self.runningPoll and not self.pendingWakeup:
+            self.pendingWakeup = True
+            os.write(self.pipetrick[1], 'c')
 
 
     # Registers a new file handle 'fd', monitoring  for 'events' (libvirt