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

Claudio Bley cbley at av-test.de
Thu Feb 13 15:22:47 UTC 2014


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(+)

diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java
index 95c13cb..3cfb8fd 100644
--- a/src/main/java/org/libvirt/Library.java
+++ b/src/main/java/org/libvirt/Library.java
@@ -7,6 +7,8 @@ import com.sun.jna.Native;
 import com.sun.jna.Pointer;
 import com.sun.jna.ptr.PointerByReference;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 /**
  * This class represents an instance of the JNA mapped libvirt
  * library.
@@ -17,6 +19,8 @@ import com.sun.jna.ptr.PointerByReference;
  * implementing the public API.
  */
 final class Library {
+    private static AtomicBoolean runLoop = new AtomicBoolean();
+
     final static Libvirt libvirt;
 
     // an empty string array constant
@@ -85,4 +89,91 @@ final class Library {
             }
         }
     }
+
+    /**
+     * Initialize the event loop.
+     *
+     * Registers a default event loop implementation based on the
+     * poll() system call.
+     * <p>
+     * Once registered, the application has to invoke
+     * {@link #processEvent} in a loop or call {@link #runEventLoop}
+     * in another thread.
+     * <p>
+     * Note: You must call this function <em>before</em> connecting to
+     *       the hypervisor.
+     *
+     * @throws LibvirtException on failure
+     *
+     * @see #processEvent
+     * @see #runLoop
+     */
+    public static void initEventLoop() throws LibvirtException {
+        processError(libvirt.virEventRegisterDefaultImpl());
+    }
+
+    /**
+     * Run one iteration of the event loop.
+     * <p>
+     * Applications will generally want to have a thread which invokes
+     * this method in an infinite loop:
+     * <pre>
+     * {@code while (true) connection.processEvent(); }
+     * </pre>
+     * <p>
+     * Failure to do so may result in connections being closed
+     * unexpectedly as a result of keepalive timeout.
+     *
+     * @throws LibvirtException on failure
+     *
+     * @see #initEventLoop()
+     */
+    public static void processEvent() throws LibvirtException {
+        processError(libvirt.virEventRunDefaultImpl());
+    }
+
+    /**
+     * Runs the event loop.
+     *
+     * This method blocks until {@link #stopEventLoop} is called or an
+     * exception is thrown.
+     * <p>
+     * Usually, this method is run in another thread.
+     *
+     * @throws LibvirtException     if there was an error during the call of a
+     *                              native libvirt function
+     * @throws InterruptedException if this thread was interrupted by a call to
+     *                              {@link java.lang.Thread#interrupt() Thread.interrupt()}
+     */
+    public static void runEventLoop() throws LibvirtException, InterruptedException {
+        runLoop.set(true);
+        do {
+            processEvent();
+            if (Thread.interrupted())
+                throw new InterruptedException();
+        } while (runLoop.get());
+    }
+
+    /**
+     * Stops the event loop.
+     *
+     * This methods stops an event loop when an event loop is
+     * currently running, otherwise it does nothing.
+     *
+     * @see #runEventLoop
+     */
+    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);
+        }
+    }
 }
diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java
index 2bc5b6b..ed52bd3 100644
--- a/src/main/java/org/libvirt/jna/Libvirt.java
+++ b/src/main/java/org/libvirt/jna/Libvirt.java
@@ -187,6 +187,10 @@ public interface Libvirt extends Library {
     void virResetLastError();
     void virSetErrorFunc(Pointer userData, VirErrorCallback callback);
 
+    // Event loop functions.
+    int virEventRegisterDefaultImpl();
+    int virEventRunDefaultImpl();
+
     // Domain functions
     int virDomainAbortJob(DomainPointer virDomainPtr);
     int virDomainAttachDevice(DomainPointer virDomainPtr, String deviceXML);
-- 
1.7.9.5




More information about the libvir-list mailing list