There can only be a single connection close listener registered
per connection object.
Signed-off-by: Claudio Bley <cbley(a)av-test.de>
---
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