[libvirt] Domain Event Handlers

Daniel P. Berrange berrange at redhat.com
Mon May 18 12:54:28 UTC 2009


On Mon, May 18, 2009 at 01:25:35PM +0100, Daniel P. Berrange wrote:
> On Thu, May 14, 2009 at 06:43:10PM -0700, Noah Zoschke wrote:
> > Hello,
> > 
> > I have been playing around with the libvirt domain event handlers in  
> > Python and am seeing something surprising. I am using trunk libvirt  
> > and `event-test.py` with some more of the debugging strings uncommented.
> > 
> > When I trigger my first event:
> 
> [snip]
> 
> > So my handler is always one event behind.
> > 
> > This behavior is not intended is it? Am I missing either something in  
> > `event-test.py` or in how I am using virsh that would correct this  
> > behavior?
> 
> This is not intended behaviour.  I have verified that I see the same
> problem when running the event-test.py demo program. The C based
> example  event-test.c  does work correctly. So either this is a bug
> in the python demo program, or a bug in the python APIs for events.
> Not sure which yet...

The demo program is horribly broken wrt handling timeouts

Also the python binding was not incrementing the ref count on
the domain objects it was wrapping.

Daniel

diff -r 08f3de2814fb examples/domain-events/events-python/event-test.py
--- a/examples/domain-events/events-python/event-test.py	Mon May 18 13:15:33 2009 +0100
+++ b/examples/domain-events/events-python/event-test.py	Mon May 18 13:53:59 2009 +0100
@@ -6,6 +6,8 @@ import select
 mypoll = select.poll()
 TIMEOUT_MS = 1000
 
+debug = False
+
 # handle globals
 h_fd       = 0
 h_events   = 0
@@ -66,8 +68,9 @@ def myPollEventToEventHandleType(events)
     return ret;
 
 def myAddHandle(fd, events, cb, opaque):
-    global h_fd, h_events, h_cb, h_opaque
-    #print "Adding Handle %s %s %s %s" % (str(fd), str(events), str(cb), str(opaque))
+    global h_fd, h_events, h_cb, h_opaque, debug
+    if debug:
+        print "Adding Handle %s %s %s %s" % (str(fd), str(events), str(cb), str(opaque))
     h_fd = fd
     h_events = events
     h_cb = cb
@@ -76,36 +79,48 @@ def myAddHandle(fd, events, cb, opaque):
     return 0
 
 def myUpdateHandle(watch, event):
-    global h_fd, h_events
-    #print "Updating Handle %s %s" % (str(h_fd), str(event))
+    global h_fd, h_events, debug
+    if debug:
+        print "Updating Handle %s %s" % (str(h_fd), str(event))
     h_events = event
     mypoll.unregister(h_fd)
     mypoll.register(h_fd, myEventHandleTypeToPollEvent(event))
 
 def myRemoveHandle(watch):
-    global h_fd
-    #print "Removing Handle %s" % str(h_fd)
+    global h_fd, debug
+    if debug:
+        print "Removing Handle %s" % str(h_fd)
     mypoll.unregister(h_fd)
     h_fd = 0
     return h_opaque
 
 def myAddTimeout(timeout, cb, opaque):
-    global t_active, t_timeout, t_cb, t_opaque
-    #print "Adding Timeout %s %s %s" % (str(timeout), str(cb), str(opaque))
-    t_active = 1;
+    global t_active, t_timeout, t_cb, t_opaque, debug
+    if debug:
+        print "Adding Timeout %s %s %s" % (str(timeout), str(cb), str(opaque))
+    if timeout == -1:
+        t_active = 0
+    else:
+        t_active = 1
     t_timeout = timeout;
     t_cb = cb;
     t_opaque = opaque;
     return 0
 
 def myUpdateTimeout(timer, timeout):
-    global t_timeout
-    #print "Updating Timeout %s %s" % (str(timer), str(timeout))
+    global t_timeout, t_active, debug
+    if debug:
+        print "Updating Timeout %s %s" % (str(timer), str(timeout))
+    if timeout == -1:
+        t_active = 0
+    else:
+        t_active = 1
     t_timeout = timeout;
 
 def myRemoveTimeout(timer):
-    global t_active
-    #print "Removing Timeout %s" % str(timer)
+    global t_active, debug
+    if debug:
+        print "Removing Timeout %s" % str(timer)
     t_active = 0;
     return t_opaque
 
@@ -159,6 +174,8 @@ def main():
 
     while 1:
         try:
+            if debug:
+                print "Poll sleep %d" % t_active
             sts = mypoll.poll(TIMEOUT_MS)
         except select.error, err:
             if err[0] == errno.EINTR:
@@ -168,17 +185,19 @@ def main():
             print "Keyboard Interrupt caught - exiting cleanly"
             break
 
+        if t_cb and t_active == 1:
+            if debug:
+                print "Invoking Timeout CB"
+            t_cb(t_timeout, t_opaque[0], t_opaque[1])
+
         if not sts:
-            #print "Timed out"
+            if debug:
+                print "Timed out"
             continue
 
         rfd = sts[0][0]
         revents = sts[0][1]
 
-        if t_active:
-            #print "Invoking Timeout CB"
-            t_cb(t_timeout, t_opaque[0], t_opaque[1])
-
         if revents & select.POLLHUP:
             print "Reset by peer";
             return -1;
diff -r 08f3de2814fb python/libvir.c
--- a/python/libvir.c	Mon May 18 13:15:33 2009 +0100
+++ b/python/libvir.c	Mon May 18 13:53:59 2009 +0100
@@ -1653,6 +1653,7 @@ libvirt_virConnectDomainEventCallback(vi
     LIBVIRT_ENSURE_THREAD_STATE;
 
     /* Create a python instance of this virDomainPtr */
+    virDomainRef(dom);
     pyobj_dom = libvirt_virDomainPtrWrap(dom);
     pyobj_dom_args = PyTuple_New(2);
     if(PyTuple_SetItem(pyobj_dom_args, 0, pyobj_conn_inst)!=0) {



Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list