On Fri, Jul 27, 2012 at 11:39:55 +0100, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Update the remote driver to use the virNetClient close callback
to trigger the virConnectPtr close callbacks
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/datatypes.h | 2 ++
src/libvirt.c | 3 ++-
src/remote/remote_driver.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/src/datatypes.h b/src/datatypes.h
index 8ac9171..a303cdc 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -191,6 +191,8 @@ struct _virConnect {
virConnectCloseFunc closeCallback;
void *closeOpaque;
virFreeCallback closeFreeCallback;
+ bool closeDispatch;
+ unsigned closeUnregisterCount;
int refs; /* reference count */
};
diff --git a/src/libvirt.c b/src/libvirt.c
index 160ace7..d352cfd 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -18711,7 +18711,8 @@ int virConnectUnregisterCloseCallback(virConnectPtr conn,
}
conn->closeCallback = NULL;
- if (conn->closeFreeCallback)
+ conn->closeUnregisterCount++;
+ if (!conn->closeDispatch && conn->closeFreeCallback)
conn->closeFreeCallback(conn->closeOpaque);
conn->closeFreeCallback = NULL;
conn->closeOpaque = NULL;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a69e69a..9ac27b2 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -320,6 +320,32 @@ enum virDrvOpenRemoteFlags {
};
+static void remoteClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED,
+ int reason,
+ void *opaque)
+{
+ virConnectPtr conn = opaque;
+
+ virMutexLock(&conn->lock);
+ if (conn->closeCallback) {
+ virConnectCloseFunc closeCallback = conn->closeCallback;
+ void *closeOpaque = conn->closeOpaque;
+ virFreeCallback closeFreeCallback = conn->closeFreeCallback;
+ unsigned closeUnregisterCount = conn->closeUnregisterCount;
+
+ VIR_DEBUG("Triggering connection close callback %p reason=%d",
+ conn->closeCallback, reason);
+ conn->closeDispatch = true;
+ virMutexUnlock(&conn->lock);
+ closeCallback(conn, reason, closeOpaque);
+ virMutexLock(&conn->lock);
+ conn->closeDispatch = false;
+ if (conn->closeUnregisterCount != closeUnregisterCount)
+ closeFreeCallback(closeOpaque);
+ }
+ virMutexUnlock(&conn->lock);
+}
+
/*
* URIs that this driver needs to handle:
*
Looks good. However, do we need to protect against the following scenario:
- remoteClientCloseFunc locks conn, remembers stuff, unlocks conn
- virConnectUnregisterCloseCallback
- virConnectRegisterCloseCallback
- virConnectUnregisterCloseCallback
- remoteClientCloseFunc finishes
Now the second registered callback won't be unregistered. It doesn't seem like
something that could happen in the real world, though.
Jirka