On 07/20/2012 08:21 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Define a new virConnectSetCloseCallback() public API which allows
registering a callback to be invoked when the connection to a
hypervisor is closed. The callback is provided with the reason for
the close, which may be 'error', 'eof' or 'keepalive'.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
include/libvirt/libvirt.h.in | 40 +++++++++++++++++++++-------
src/datatypes.c | 4 +++
src/datatypes.h | 5 ++++
src/libvirt.c | 60 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 6 +++++
5 files changed, 105 insertions(+), 10 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e34438c..85d8c8a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -49,6 +49,17 @@ extern "C" {
* defines VIR_ENUM_SENTINELS. Enumerations for bit values do not
* have a *_LAST value, but additional bits may be defined. */
+/*
+ * virFreeCallback:
+ * @opaque: opaque user data provided at registration
+ *
+ * Type for a domain event callback when the event is deregistered and
+ * need to be freed, @opaque is provided along with the callback at
+ * registration time
+ */
+typedef void (*virFreeCallback)(void *opaque);
We're now using this for more than just domain events; the comment needs
a slight update. Maybe:
Type for a callback cleanup function to be paired with a callback. This
function will be called as a final chance to clean up the @opaque
registered with the primary callback, at the time when the primary
callback is deregistered.
+++ b/src/datatypes.c
@@ -115,6 +115,10 @@ virReleaseConnect(virConnectPtr conn) {
virMutexLock(&conn->lock);
+ if (conn->closeOpaque &&
+ conn->closeFreeCallback)
+ conn->closeFreeCallback(conn->closeOpaque);
I'm still not sure I like filtering on NULL opaque. Our other uses of a
virFreeCallback include src/fdstream.c:virFDStreamRemoveCallback, and
there we call fdst->ff without regards to whether fdst->opaque is null.
+int virConnectSetCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ virMutexLock(&conn->lock);
+
+ if (conn->closeCallback) {
+ virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("A close callback is already registered"));
+ goto error;
+ }
Do we want to allow deregistration of a close callback (we have
virConnectDomainEventDeregister, after all).
--
Eric Blake eblake(a)redhat.com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org