[libvirt] [libvirt-java] [PATCH 39/65] Introduce event loop support

Claudio Bley cbley at av-test.de
Wed Mar 26 08:37:46 UTC 2014


At Fri, 21 Feb 2014 11:03:49 +0000,
Daniel P. Berrange wrote:
> 
> On Thu, Feb 13, 2014 at 04:22:47PM +0100, Claudio Bley wrote:
> > Add initEventLoop(), processEvent(), runEventLoop() and stopEventLoop()
> > static methods to the Library class.
> > 
> > Signed-off-by: Claudio Bley <cbley at av-test.de>
> > ---
> >  src/main/java/org/libvirt/Library.java     |   91 ++++++++++++++++++++++++++++
> >  src/main/java/org/libvirt/jna/Libvirt.java |    4 ++
> >  2 files changed, 95 insertions(+)
> 
> ACK

This is what I'd want to squash in prior pushing the patch in order to
avoid failures due to virEventAddTimeout when stopping an event loop
as suggested by you, Eric[1] and Jim[2].

Since this code requires the virEventUpdateTimeout function, I've
added it into patch 36/65 as you requested[3].

[1]: http://www.redhat.com/archives/libvir-list/2014-March/msg00144.html
[2]: http://www.redhat.com/archives/libvir-list/2014-March/msg00168.html
[3]: http://www.redhat.com/archives/libvir-list/2014-February/msg01318.html

---
diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java
--- a/src/main/java/org/libvirt/Library.java
+++ b/src/main/java/org/libvirt/Library.java
@@ -1,6 +1,7 @@
 package org.libvirt;

 import org.libvirt.jna.Libvirt;
+import org.libvirt.jna.Libvirt.VirEventTimeoutCallback;
 import static org.libvirt.ErrorHandler.processError;

 import com.sun.jna.Native;
@@ -8,6 +9,7 @@
 import com.sun.jna.ptr.PointerByReference;

 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;

 /**
  * This class represents an instance of the JNA mapped libvirt
@@ -20,6 +22,14 @@
  */
 final class Library {
     private static AtomicBoolean runLoop = new AtomicBoolean();
+    private static AtomicInteger timerID = new AtomicInteger(-1);
+    private static VirEventTimeoutCallback timer = new VirEventTimeoutCallback() {
+            @Override
+            public void tick(int id, Pointer p) {
+                // disable myself again right after being triggered
+                libvirt.virEventUpdateTimeout(id, -1);
+            }
+        };

     final static Libvirt libvirt;

@@ -109,7 +119,18 @@
      * @see #runLoop
      */
     public static void initEventLoop() throws LibvirtException {
-        processError(libvirt.virEventRegisterDefaultImpl());
+        if (timerID.get() == -1) {
+            processError(libvirt.virEventRegisterDefaultImpl());
+
+            // add a disabled timer which is used later to break out
+            // of the event loop
+            int id = processError(libvirt.virEventAddTimeout(-1, timer, null, null));
+
+            // remove this timer when there already is another one
+            if (!timerID.compareAndSet(-1, id)) {
+                libvirt.virEventRemoveTimeout(id);
+            }
+        }
     }

     /**
@@ -164,16 +185,10 @@
      */
     public static void stopEventLoop() throws LibvirtException {
         if (runLoop.getAndSet(false)) {
-            // add a timeout which fires immediately so that the processEvent
-            // method returns if it is waiting
-            libvirt.virEventAddTimeout(0, new org.libvirt.jna.Libvirt.VirEventTimeoutCallback() {
-                    @Override
-                    public void tick(int id, Pointer p) {
-                        // remove itself right after it served its purpose
-                        libvirt.virEventRemoveTimeout(id);
-                    }
-                },
-                null, null);
+            // fire the timer immediately
+            int timer = timerID.get();
+            if (timer >= 0)
+                libvirt.virEventUpdateTimeout(timer, 0);
         }
     }
 }




More information about the libvir-list mailing list