There can only be a single connection close listener registered
per connection object.

Signed-off-by: Claudio Bley <[email protected]>
---
 src/main/java/org/libvirt/Connect.java     |   57 ++++++++++++++++++++++++++++
 src/main/java/org/libvirt/jna/Libvirt.java |   11 ++++++
 2 files changed, 68 insertions(+)

diff --git a/src/main/java/org/libvirt/Connect.java 
b/src/main/java/org/libvirt/Connect.java
index 10fc2e8..f597826 100644
--- a/src/main/java/org/libvirt/Connect.java
+++ b/src/main/java/org/libvirt/Connect.java
@@ -46,6 +46,22 @@ public class Connect {
         return new HashMap[size];
     }
 
+    private class CloseFunc implements Libvirt.VirConnectCloseFunc {
+        final ConnectionCloseListener listener;
+
+        CloseFunc(ConnectionCloseListener l) {
+            this.listener = l;
+        }
+
+        @Override
+        public void callback(ConnectionPointer VCP, int reason, Pointer 
opaque) {
+            this.listener.onClose(Connect.this,
+                                  getConstant(ConnectionCloseReason.class, 
reason));
+        }
+    }
+
+    private CloseFunc registeredCloseFunc = null;
+
     /**
      * Event IDs.
      */
@@ -267,6 +283,11 @@ public class Connect {
         int success = 0;
         if (VCP != null) {
             success = libvirt.virConnectClose(VCP);
+
+            // if the connection has been closed (i.e. the reference count is
+            // down to zero), forget about the registered close function
+            if (success == 0) registeredCloseFunc = null;
+
             // If leave an invalid pointer dangling around JVM crashes and 
burns
             // if someone tries to call a method on us
             // We rely on the underlying libvirt error handling to detect that
@@ -277,6 +298,42 @@ public class Connect {
     }
 
     /**
+     * Register the specified connection close listener to receive 
notifications
+     * when this connection is closed.
+     * <p>
+     * <strong>Note:</strong> There can only be at most one registered listener
+     *                        at a time.
+     * @param   l  the connection close listener
+     * @throws  LibvirtException on failure
+     * @see #unregisterCloseListener
+     */
+    public void registerCloseListener(final ConnectionCloseListener l) throws 
LibvirtException {
+        CloseFunc cf = new CloseFunc(l);
+
+        processError(libvirt.virConnectRegisterCloseCallback(this.VCP,
+                                                             cf,
+                                                             null,
+                                                             null));
+        this.registeredCloseFunc = cf;
+    }
+
+    /**
+     * Unregister the previously registered close listener.
+     *
+     * When there currently is no registered close listener, this method
+     * does nothing.
+     *
+     * @see #registerCloseListener
+     */
+    public void unregisterCloseListener() throws LibvirtException {
+        if (this.registeredCloseFunc != null) {
+            processError(libvirt.virConnectUnregisterCloseCallback(this.VCP,
+                                                                   
this.registeredCloseFunc));
+            this.registeredCloseFunc = null;
+        }
+    }
+
+    /**
      * Compares the given CPU description with the host CPU
      *
      * @see <a
diff --git a/src/main/java/org/libvirt/jna/Libvirt.java 
b/src/main/java/org/libvirt/jna/Libvirt.java
index 1eaeab8..e4b2cfb 100644
--- a/src/main/java/org/libvirt/jna/Libvirt.java
+++ b/src/main/java/org/libvirt/jna/Libvirt.java
@@ -65,6 +65,13 @@ public interface Libvirt extends Library {
     }
 
     /**
+     * Callback interface for connection closed events.
+     */
+    interface VirConnectCloseFunc extends Callback {
+        void callback(ConnectionPointer VCP, int reason, Pointer opaque);
+    }
+
+    /**
      * Domain Event Callbacks
      */
 
@@ -162,6 +169,10 @@ public interface Libvirt extends Library {
     // Register Domain Event Callbacks
     int virConnectDomainEventRegisterAny(ConnectionPointer virConnectPtr, 
DomainPointer virDomainPtr, int eventID, VirDomainEventCallback cb, Pointer 
opaque, Libvirt.VirFreeCallback freecb);
 
+    int virConnectRegisterCloseCallback(ConnectionPointer virConnectPtr, 
VirConnectCloseFunc cb,
+                                        Pointer opaque, Pointer freeOpaque);
+    int virConnectUnregisterCloseCallback(ConnectionPointer virConnectPtr, 
VirConnectCloseFunc cb);
+
     int virConnectDomainEventDeregisterAny(ConnectionPointer virConnectPtr, 
int callbackID) ;
     void virConnSetErrorFunc(ConnectionPointer virConnectPtr, Pointer 
userData, VirErrorCallback callback);
     int virConnectIsAlive(ConnectionPointer virConnectPtr);
-- 
1.7.9.5

--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to