There can only be a single connection close listener registered per connection object. Signed-off-by: Claudio Bley <cbley@xxxxxxxxxx> --- 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 libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list